[SCM] Gerris Flow Solver branch, debian-unstable, updated. gerris-20090512-dfsg.1-1-6-g56a5275

Drew Parsons dparsons at debian.org
Tue Nov 24 12:16:38 UTC 2009


The following commit has been merged in the debian-unstable branch:
commit ac9459311890284f3e895760333379f60c5130b0
Author: Drew Parsons <dparsons at debian.org>
Date:   Tue Nov 24 22:41:28 2009 +1100

    Install upstream source from DFSG-free tarball.
    
    using gerris_20091109-dfsg.1.orig.tar.gz

diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..c435447
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,15 @@
+Original Authors
+----------------
+Stéphane Popinet   <popinet at users.sf.net>
+Sébastien Delaux   <s.delaux at niwa.co.nz> : Moving solid boundaries
+
+Contributors
+------------
+Marcelo E. Magallon, Ruben Molina, Drew Parsons: Debian packages
+Ruben Scardovelli: - author of the Fortran version of gfs_plane_alpha()
+      		   - Mixed Youngs-Centered VOF normal calculation
+Ivan Adam Vari: RPM packages.
+Daniel Fuster: gfsjoin script
+Rohallah Tavakoli: initial implementation of VTK and Tecplot output
+Norbert Beckmann: R*-tree implementation used in the terrain module
+Thierry Letellier, Laurent Roblou: FES2004 tidal atlas library
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+		     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
+convey 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 2 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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..d785692
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,4618 @@
+Wed Nov 11 03:10:05 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-11-09
+
+Tue Nov 10 02:32:04 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * wavewatch module supports version 3.12
+
+Sat Nov  7 03:10:06 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New object GfsEventList
+
+Fri Nov  6 06:49:24 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Wavewatch module supports versions 3.14 and 2.22
+
+Thu Nov  5 07:46:12 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed compiler warnings for FES2004
+
+Wed Nov  4 03:10:08 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-11-02
+
+Tue Nov  3 06:46:05 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated spurious currents test cases
+
+Mon Nov  2 00:36:58 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated advection test case
+
+Sun Nov  1 15:18:54 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Metrics descend from GfsVariableMetric
+
+Sun Nov  1 15:15:55 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Macros only work with gawk (i.e. not mawk)
+
+Thu Oct 29 18:36:51 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'cosine bell' test case
+
+Thu Oct 29 16:55:08 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * OutputScalarSum, OutputScalarNorm etc... take metric into account
+
+Thu Oct 29 11:48:18 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Godunov advection scheme takes metric into account
+
+Fri Aug  7 11:05:42 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Update of the strouhal testcase
+
+Wed Oct 28 14:26:54 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * coarse->fine and fine->coarse interpolations take metric into account
+  
+  in order to conserve quantities.
+
+Wed Oct 28 13:14:41 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * MetricCubed takes an optional "level" parameter
+
+Tue Oct 27 11:59:14 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Extended "Cubed" metric to entire "expanded spherical cube"
+
+Sun Oct 25 03:57:09 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-10-24
+
+Sat Oct 24 21:09:27 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases
+
+Fri Oct 23 16:46:58 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_cfl() takes metric into account
+
+Fri Oct 16 16:57:51 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Optimisation of GfsMetricLonLat and GfsMetricCubed
+
+Wed Oct 14 16:31:18 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * "Cubed sphere" metric
+
+Tue Oct 13 13:34:58 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Adaptivity takes "minlevel" into account properly
+
+Thu Oct  8 10:08:54 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsMapFunction
+
+Wed Oct  7 15:43:27 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * CFL calculation for GfsRiver takes metric into account
+
+Wed Oct  7 14:43:44 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Hydrostatic balance for 2nd-order curvilinear scheme in GfsRiver
+
+Tue Sep 29 15:25:59 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * General Orthogonal Coordinates
+
+Fri Sep 25 22:36:30 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Longitude-latitude metric
+
+Thu Oct 22 16:22:34 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsVariableStreamFunction
+
+Wed Oct 21 12:13:04 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Support for "rotated" periodic boundaries
+
+Tue Oct 20 13:28:15 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New "relative" option for GfsOutputErrorNorm
+
+Wed Oct 21 02:51:19 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-10-19
+
+Tue Oct 20 09:39:11 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed missing header in OutputSimulation
+
+Sat Sep 19 02:57:00 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-09-18
+
+Fri Sep 18 16:18:17 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Support for "preloaded" modules
+
+Thu Sep 17 13:14:56 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Units of VariableTerrain are properly reset
+
+Thu Sep 17 02:56:02 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-09-16
+
+Wed Sep 16 15:28:20 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for CGD/GTS files and multiple GfsFunctions
+
+Wed Sep 16 12:14:20 NZST 2009  Matthieu Castellazzi <m.castellazzi at niwa.co.nz>
+  * Some fixes to the rpm spec file
+
+Thu Sep 10 03:04:01 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-09-08
+
+Wed Sep  9 10:43:57 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * RPM includes man pages
+
+Fri Sep  4 03:06:32 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-09-02
+
+Thu Sep  3 09:20:21 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Cosmetics
+
+Wed Sep  2 17:04:08 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsSourceControlField
+
+Thu Aug 27 03:00:40 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-08-19
+
+Thu Aug 20 11:26:34 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsSourceFlux
+
+Wed Aug 26 16:47:18 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_streamline_new()
+
+Wed Aug 26 12:03:13 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Cosmetics for wave model
+
+Wed Aug 26 12:01:46 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * BcSubcritical now tolerates negative depths
+
+Thu Aug 20 11:25:31 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * H and P terrain reconstruction for GfsVariableTerrain is optional
+
+Thu Aug 20 11:21:42 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_function_expression()
+  
+  When specifying two GfsFunctions in a row.
+
+Thu Aug 20 09:55:25 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsRefineTerrain defines two new variables "dmin" and "dmax"
+
+Thu Aug  6 03:38:44 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-08-05
+
+Wed Aug  5 21:56:50 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added stability correction for wind wave model
+
+Wed Aug  5 21:47:56 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GSE alleviation for GfsWave wind wave model
+
+Thu Jul 30 15:23:48 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete GfsAdaptCurvature
+
+Thu Jul 30 15:23:13 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Important improvements to GfsAdaptError
+
+Thu Jul 30 12:16:36 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Minor optimisation of gfs_domain_solid_force()
+
+Tue Jul 28 16:37:09 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed negative wave actions in wavewatch module
+
+Mon Jul 27 12:35:18 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsOutputSolidForce can take an optional weight argument
+
+Mon Jul 27 11:03:55 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for incorrect maxtag MPI value
+
+Fri Jul 24 13:22:56 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added option to use "bubble partitioning"
+
+Fri Jul 24 11:21:32 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed debian changelog generation
+
+Fri Jul 24 09:17:59 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-07-21
+
+Wed Jul 22 10:49:22 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Fix for moving second order bug with merged cells
+
+Thu Jul 23 16:55:44 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_traverse_and_bc()
+  
+  For overlapping computation and communications.
+
+Thu Jul 23 09:37:38 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New interface for gfs_domain_locate() and gfs_domain_boundary_locate()
+
+Wed Jul 22 16:34:37 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Overlapping communications and computations
+  
+  Only using gfs_traverse_and_homogeneous_bc() for now.
+
+Wed Jul 22 11:57:30 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Daily script uses the parallel version
+
+Wed Jul 22 11:54:01 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Improved parallel example graph
+
+Tue Jul 14 13:21:20 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New parallel vortex street example
+
+Tue Jul 21 20:41:01 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Simplified divergence redistribution of moving boundaries
+
+Tue Jul 21 11:59:16 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Moving cylinder test case
+
+Mon Jul 20 19:39:08 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Important bug fix for graph partitioning
+  
+  i.e. the "-p" option of gerris. Incorrect object casting between GtsWGnode and
+  GfsBox were causing segfaults for some configurations.
+
+Mon Jun 29 11:24:01 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Divergence redistribution between merged cells for moving boundaries
+
+Thu Jun 25 10:30:25 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Fix for problem with small cells and moving solid interface in second 
+  order method
+
+Tue Jun 16 10:16:36 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Bug fix for dividing by zero in moving code
+
+Sun Jul 19 02:12:41 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 2009-07-17
+
+Sat Jul 18 10:28:40 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsEventBalance flows can transfer more than one box at a time
+
+Fri Jul 17 14:55:08 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Various small fixes
+
+Thu Jul 16 12:13:49 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_locate() uses a Cartesian array for fast indexing
+  
+  The previous systematic traversal of all the GfsBoxes was very slow 
+  (when the number of boxes was large e.g. due to "splitting"). 
+  This was particularly noticeable for the VOF algorithm (which does
+  many locate() calls to reconstruct local Cartesian stencils).
+
+Wed Jul 15 16:31:22 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New option '--event' for gerris2D/3D
+
+Wed Jul 15 20:57:44 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed GfsVariableCurvature timers
+
+Wed Jul 15 15:51:13 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New '--pid' option for gerris2D/3D
+
+Tue Jul 14 19:18:56 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * A few fixes for OutputTiming
+
+Tue Jul 14 15:58:43 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Output timing now outputs sorted timings
+
+Tue Jul 14 15:32:49 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Entirely solid boxes can be used
+  
+  They will be automatically removed from the simulation rather than 
+  making the simulation abort with an error message.
+
+Tue Jul 14 13:36:51 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Dynamic parallel load-balancing (EventBalance)
+
+Mon Jul 13 17:30:59 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * daily script only generates launchpad snapshots
+
+Mon Jul 13 16:59:10 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed header dependency for domain.c
+
+Sun Jul 12 13:45:49 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added openmpi-bin as a dependency for debian package
+  
+  This is a workaround for the broken libopenmpi1 debian package.
+
+Sun Jun 28 23:05:55 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsBoundaryMpi is included by default (even in the serial version)
+  
+  This simplifies the code and also means that the serial version can be used
+  to join and load simulation files generated by parallel runs (e.g. a serial
+  version of GfsView ran on a different system will now be able to visualise
+  the results of a parallel run).
+
+Mon Jun 22 12:16:41 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed Debian version numbering
+
+Mon Jun 22 10:36:09 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Automatically include aclocal m4 macros
+
+Wed May 13 14:09:17 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Debian packages are built with MPI support
+
+Wed May 13 11:52:23 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added 'launchpad-snapshot' Makefile target
+
+Thu Jul  2 23:16:02 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsOutputDropletSums and GfsRemoveDroplets should now work in parallel
+  
+  and also for periodic boundary conditions in serial and in parallel.
+
+Thu Jul  9 12:39:14 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * EventBalance implements dynamic load balancing on 2 PEs only
+
+Wed Jul  8 16:46:50 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * OutputTime reports average CPU time for parallel runs
+
+Wed Jul  8 12:24:53 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * OutputBalance ignores box pids for serial runs
+
+Mon Jul  6 10:14:36 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Box positions set in the parameter file are preserved
+
+Wed Jul  1 16:29:53 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsInitFraction should now work also for parallel simulations
+  
+  It used to fail for domains containing disconnected GfsBoxes (which can
+  happen for some domain decompositions in parallel).
+
+Sun Jun 28 21:54:13 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added version info to read()/write() methods of GfsDomain
+
+Sun Jun 28 20:50:08 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New functions gfs_send_boxes() and gfs_receive_boxes()
+  
+  To move GfsBoxes between processors in parallel.
+
+Thu Jun 25 21:57:17 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Major bug fix for GfsBoundaryPeriodic
+  
+  Amazingly the implementation of the match() method seems to have been wrong
+  right from the initial implementation (then part of BoundaryMpi). Yet, despite
+  being completely inconsistent, this implementation managed to "work"
+  undetected for several years... The bug also affected parallel simulations
+  through inheritance to BoundaryMpi.
+
+Tue Jun 23 21:25:28 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for file access test in parallel
+
+Tue Jun 23 21:24:16 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Improved error messages in parallel (includes processor name)
+
+Mon Jun 22 09:39:09 NZST 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged release_21_06_09
+
+Sun Jun 21 20:01:04 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added configuration options to "--version" info
+
+Sun Jun 21 10:30:38 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsOutputSimulation can write "joined" parallel simulation files
+  
+  Only for GFS and text formats.
+
+Sun Jun 21 09:46:04 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsEventScript is only called for rank 0 PE in parallel
+
+Sat Jun 20 15:07:20 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added MPI_Finalize() as required by MPI standard
+
+Fri Jun 19 12:40:54 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added man pages for gfsjoin2D, gfsjoin3D
+
+Fri Jun 19 12:22:01 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'keep' option for gfsjoin2D
+
+Fri Jun 19 12:19:42 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsDomain automatically converts GfsBoundaryMPI into edges on read
+
+Fri Jun 19 12:18:27 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated test case references
+
+Fri Jun 19 11:27:50 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsSolidMoving/GfsSurface write() method
+
+Thu Jun 18 20:14:25 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New gfsjoin2D, gfsjoin3D tools
+  
+  These are replacing the gfsjoin script. Note however that they can only be used
+  to join parallel files created using this and later versions of Gerris. Older
+  parallel simulation files should still use the gfsjoin script.
+
+Thu Jun 18 15:18:40 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for write() method of GfsSurface
+
+Thu May 14 14:02:33 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * GfsVariableTerrain also reconstructs H and P of GfsRiver
+
+Wed May 13 21:38:58 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Adaptivity cannot coarsen by more than one level per timestep
+
+Wed May 13 10:44:30 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for incorrect generation of dependencies in tests docs
+
+Tue May 12 15:18:55 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Check that SolidMoving is used within SimulationMoving
+
+Tue May 12 15:04:30 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Renamed GfsMovingSimulation to GfsSimulationMoving
+
+Tue May 12 12:43:40 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated moving hexagon test case
+
+Tue May 12 12:26:58 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Split 2nd-order moving in moving2.c
+
+Tue May 12 11:20:11 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for remeshing of moving solids
+
+Tue May 12 11:18:31 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Diffusion now works with moving boundaries
+
+Wed May  6 17:58:23 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for SurfaceBc implementation of moving boundaries
+
+Tue May  5 23:12:14 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Solid motion is now specified through SurfaceBc
+
+Tue May  5 20:07:19 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Simplification of redistribute_destroyed_cells_content()
+
+Tue May  5 16:43:04 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Simplified moving_cell_fine_init and removed old_solid_coarse_fine
+
+Tue May  5 12:41:44 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Simplified moving_simulation_set_timestep()
+
+Mon May  4 21:06:17 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixes for memory leaks in initial moving boundary implementation
+
+Sun May  3 00:21:46 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Translating hexagon test case
+
+Sun May  3 00:19:51 NZST 2009  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Initial moving solid boundary implementation
+
+Tue May 12 11:17:42 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for corner refinement bug fix
+
+Mon May 11 16:18:28 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for violation of 'corner refinement criterion'
+
+Sat May  9 11:39:30 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * autogen.sh copies missing files
+
+Fri May  8 13:02:22 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'time_order' parameter for GfsRiver
+
+Mon May  4 21:23:46 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * More generic valgrind suppression file (ld.so.supp)
+
+Mon May  4 21:22:31 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Default boundary conditions can be set for each variable
+
+Sat May  2 23:16:28 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'cleanup' method for GfsVariable
+
+Thu Apr 30 21:08:50 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Changed meaning of gfs_simulation_get_solids() (!!)
+
+Sat May  2 21:20:48 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Debian package must depend on libgts-snapshot-dev
+
+Sat May  2 19:18:34 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fixes for 'daily' script
+
+Fri May  1 23:21:12 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * daily script properly signs debian repositories
+
+Fri May  1 20:23:08 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Divide-by-zero exceptions use <fenv.h>
+
+Sat May  2 11:25:23 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Man pages need to be distributed
+
+Fri May  1 16:28:27 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated debian package build (based on Drew Parson's)
+
+Fri May  1 16:13:55 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added man pages from debian (thanks Ruben and Drew!)
+
+Thu Apr 30 20:56:19 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Advection merging updates can be parameterised
+
+Thu Apr 30 20:49:25 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_surface_transformation()
+
+Thu Apr 30 20:42:14 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * gfs_cell_traverse_cut() can traverse "destroyed" cells
+
+Thu Apr 30 20:38:18 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Projections can use an optional initial divergence field
+
+Thu Apr 30 20:35:23 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_advance_tracers()
+
+Thu Apr 30 20:32:37 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_cell_is_small()
+
+Tue Apr 21 09:45:49 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'ppm2video' script
+  
+  Uses ffmpeg to convert PPM to (almost) any video format.
+
+Tue Apr 21 08:51:44 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated reference for 'reynolds' test case
+
+Sun Apr 19 19:24:50 NZST 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for dimensioning of GfsSurfaceBc
+
+Fri Apr  3 10:02:10 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for dependencies of examples
+
+Thu Apr  2 08:59:25 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for negative clock return values (thanks to G. McBain)
+
+Fri Mar 27 07:11:53 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * gerris.dic is installed in $prefix/share/gerris/gerris.dic
+
+Mon Mar 16 05:02:16 NZDT 2009  Daniel Fuster <dfuster at gmail.com>
+  * vim dictionary
+
+Wed Mar 18 05:41:32 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for compilation on Mac OSX 10.4, 10.5
+
+Mon Mar 16 10:34:31 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * OutputDropletSums sorts droplets by volume
+
+Sun Mar 15 06:23:12 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed dimensioning of GfsVariableCurvature
+
+Fri Mar 13 03:26:54 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for surface tension coefficient and dimensions
+
+Fri Feb 27 08:45:04 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix (again!) for module dependencies
+
+Thu Feb 26 15:28:02 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed obsolete lseek() call in RStarTree
+
+Thu Feb 26 14:41:33 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for hardcoded path in wavewatch module
+
+Wed Feb 25 13:20:51 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for incorrect 'dist' dependency in wavewatch module
+
+Tue Feb 24 09:33:43 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for 'listing' option of wavewatch
+
+Tue Feb 24 09:11:58 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fixed changelog in gerris.spec
+
+Mon Feb 23 22:31:36 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for wavewatch module makefile
+
+Mon Feb 23 22:13:58 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Automatic type checking for wavewatch C/Fortran linking
+
+Mon Feb 23 18:17:04 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Wavewatch initialisation files are created in the background
+
+Mon Feb 23 14:08:07 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'wavewatch' module
+
+Fri Feb 20 18:27:36 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for energy calculation in GfsWave
+
+Tue Feb  3 13:00:35 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Applied patch by Laurent Roblou to FES2004 library
+
+Mon Feb  2 22:51:53 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsVariableFunction
+  
+  Used to efficiently refine adaptively a variable defined by a GfsFunction.
+
+Thu Jan 29 12:53:08 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Small optimisation for dry cells in GfsRiver
+
+Fri Jan 16 10:01:46 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  UNDO: New GfsBcValve BC for GfsRiver
+
+Thu Jan 29 12:45:25 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Cron script darcs pull from the correct repositories
+
+Thu Jan 29 12:44:08 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added fortran dependency for new stokes module
+
+Wed Jan 28 19:26:03 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Small optimisation for gfs_domain_traverse_merged()
+
+Wed Jan 28 19:24:51 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Less strict check for parabola test case
+
+Tue Jan 27 14:28:46 NZDT 2009  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated GfsView parameter files for updated GfsGlLinear object
+
+Wed Jan 21 09:34:30 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for hardcoding of path in Terrain module
+
+Fri Jan 16 15:55:16 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New GfsVariableTerrain for adaptive refinement of GfsRiver
+
+Fri Jan 16 10:01:46 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New GfsBcValve BC for GfsRiver
+
+Fri Aug 22 16:18:05 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsInitStokesWave
+
+Mon Jul 28 18:03:05 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Iterative Stokes wave solver of John Chaplin
+
+Tue May  6 11:11:31 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added GFS_FES2004 environment variable
+
+Tue Sep 18 10:06:46 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New EventBalance object for parallel load-balancing
+
+Sun Sep  2 19:11:05 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New VariableDiagonal for Poisson solver diagonal dominance evaluation
+
+Thu Jan 15 16:19:18 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated GfsRiver examples
+
+Sat Jan 10 23:35:53 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'hump' GfsRiver example
+
+Fri Jan  9 16:54:59 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New dam break example
+
+Thu Jan 22 17:02:28 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated parabola test case
+
+Thu Jan 22 11:50:03 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * SourceCoriolis properly takes friction term into account
+
+Thu Jan 22 11:33:18 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Friction for the River model is implemented using SourceCoriolis
+
+Thu Jan 22 11:32:50 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for terrain module when refining an existing mesh
+
+Thu Jan 22 10:07:21 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Log timing statistics for events
+
+Fri Jan 16 12:56:08 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for ppmcombine
+
+Thu Jan 15 16:20:22 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Updated parabola test case
+
+Thu Jan 15 16:19:46 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for incorrect write() method of GfsRefineTerrain
+
+Thu Jan 15 16:08:30 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * stderr and stdout are muted in parallel
+
+Thu Jan 15 16:07:15 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_all_reduce()
+
+Thu Jan 15 00:19:19 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Consistent descriptions and derived variables for GfsRiver
+
+Thu Jan 15 00:15:30 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Removed Riemann Roe solver from GfsRiver
+
+Thu Jan 15 00:14:54 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for overflow in gfscompare
+
+Thu Jan 15 00:14:08 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsInit erasing variables' descriptions
+
+Wed Jan 14 20:56:35 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Added timers to GfsRiver
+
+Sun Jan 11 22:30:03 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bathymetry reconstruction ensures hydrostatic balance
+
+Sat Jan 10 14:39:03 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * New 'parabola' test case for GfsRiver
+
+Sat Jan 10 13:53:47 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Cleaned up GfsRiver code
+
+Fri Jan  9 20:48:46 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Topography source terms for GfsRiver are balanced also with adaptivity
+
+Fri Jan  9 20:48:25 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_remove_ponds()
+
+Wed Dec 17 15:01:10 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Uses the standard definitions for H and Zb
+
+Wed Dec 10 17:21:25 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Implementation of the Audusse et al scheme
+
+Wed Dec 10 14:53:56 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Wetting-drying for GfsRiver
+
+Wed Dec 10 10:59:26 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Topographic source terms for River model
+
+Wed Dec 10 09:43:48 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for HLLC riemann solver
+
+Tue Dec  9 11:16:40 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * 2nd-order non-linear shallow-water solver
+
+Tue Dec  9 10:58:37 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * BcSubcritical boundary condition
+
+Tue Dec  9 10:50:56 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_center_minmod_gradient
+
+Fri Nov 14 13:53:37 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added "none" option for gradient of AdvectionParams
+  
+  This means that the advection schemes can be made first-order in space.
+
+Fri Nov 14 13:51:23 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Initial nonlinear shallow-water solver
+  
+  1D, first-order in space and time.
+
+Fri Jan  9 16:55:42 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * Fix for hevea bug in gfs2doc
+
+Thu Dec 18 11:29:58 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Parallel outputs are only done for files with '%d' format
+
+Wed Dec 17 15:02:55 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for OutputScalarSum in parallel
+
+Thu Jan  8 15:05:31 NZDT 2009  Stephane Popinet <popinet at users.sf.net>
+  * OutputTime also outputs real elapsed time
+
+Wed Dec 10 09:44:10 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * OutputSimulation was not talking dimensioning into account for text format
+
+Tue Dec  2 15:11:13 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for BC of diffusion equation
+
+Fri Nov 28 13:31:55 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Gnuplot output from gfs2oogl takes mapping into account
+
+Fri Nov 28 13:29:57 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * OutputParticle now derives from OutputLocation
+  
+  Note also that the syntax has changed.
+
+Fri Nov  7 12:24:53 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * ASCII float conversion format option for OutputSimulation
+
+Fri Nov  7 11:08:52 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Improved robustness of VOF volume computation
+
+Tue Nov  4 10:08:45 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Slip length in BcNavier is now a GfsFunction
+
+Tue Nov  4 09:55:31 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsRemoveDroplets (thanks to G. Tomar)
+
+Tue Nov  4 09:41:47 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed dimensioning of OutputSolidForce.
+
+Thu Oct 30 17:26:06 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Dimensioning for AdaptGradient
+
+Tue Oct 28 16:54:01 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Dimensioning of Flather boundary conditions
+
+Fri Oct 24 20:23:05 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New 'ppm2theora' script
+
+Fri Oct 24 17:10:35 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * 'tides' example uses new 3D ocean code and scaling system
+
+Fri Oct 24 17:08:37 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * rsurfacedraw outputs aspect ratio statistics
+
+Thu Oct 23 09:52:22 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed dimensioning of GfsEventHarmonic
+
+Wed Oct 22 15:31:41 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * GTS and CGD files take mapping into account
+
+Wed Oct 22 12:35:48 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Terrain databases were incompatible between 32 and 64 bits
+  
+  This is fixed but you will need to regenerate the databases...
+
+Thu Oct 16 14:46:30 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Dimensioning for 3D ocean model
+
+Tue Oct 21 13:12:06 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Increased significant digits of text export
+
+Thu Oct 16 14:47:01 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New "dL" derived variable
+
+Thu Oct 16 14:46:17 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Consistent z-scaling of terrain
+
+Thu Oct 16 14:32:14 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Terrain module works only with relative bilinear coordinates
+
+Thu Oct 16 12:33:26 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed access modes for Terrain module
+
+Thu Oct  9 13:09:37 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New Terrain module uses relative sums
+  
+  This fixes round-off problems in the previous implementation of 
+  the new version. Note that the terrain databases need to be regenerated.
+
+Thu Oct  9 12:12:15 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New 'rsurfacedraw' command
+
+Mon Oct  6 10:43:15 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added new "min" and "max" derived Terrain variables
+
+Thu Oct  2 14:55:47 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New version of the terrain module using region_sum queries
+  
+  This patch contains both the old and the new version, for debugging purposes.
+
+Thu Oct  2 14:53:28 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New function r_surface_query_region_sum()
+  
+  Efficiently computes the statistics for a given region using the hierarchical
+  statistics stored in the R*-tree.
+
+Sun Oct  5 14:48:59 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed headers for compilation on Mac OSX
+
+Sun Oct  5 12:49:42 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for incorrect versioning of debian packages
+
+Mon Sep 29 16:41:14 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * darcs2dist uses sftp rather than ssh
+
+Tue Sep 23 15:30:12 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated URL for sourceforge server upgrade
+
+Thu Sep 18 13:10:31 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for dimensioning of SourceTension when using reduced gravity
+
+Thu Sep 11 09:09:52 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added missing required files for test cases
+
+Tue Sep  9 18:54:21 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric spurious currents test case
+
+Tue Sep  9 16:52:46 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric surface tension implementation
+
+Tue Sep  9 15:06:31 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Replaced GFS_VARIABLE() with GFS_VALUE() in tension.c, vof.c
+
+Tue Sep  9 16:05:13 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test case references
+
+Mon Sep  8 10:10:27 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixes for missing dimensioning
+  
+  VariableCurvature, VariableDistance, VariableFiltered, SourceTension.
+
+Sat Sep  6 10:04:37 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Implicit viscosity now works for axisymmetric domains
+  
+  The explicit viscosity scheme has also been simplified.
+
+Sat Sep  6 09:30:55 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric viscous flow past a sphere test case
+
+Wed Aug  6 10:50:48 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsAdaptError
+  
+  Uses an error estimate based on the norm of the Hessian matrix.
+
+Fri Aug  1 14:48:18 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Reimplementation of SourceVicosityExplicit
+  
+  Also works for axisymmetric flows (but for 3D flows yet).
+
+Fri Aug  1 14:47:02 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Explicit viscosity lid-driven cavity test case
+
+Thu Sep  4 16:15:05 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * gfs2oogl outputs dimensional values in mixed cells
+
+Wed Sep  3 16:56:36 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * VariableDistance now works also in 3D
+
+Thu Aug 21 13:20:26 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New user function "correctness()" for complexity of VOF interfaces
+
+Fri Aug 22 16:04:47 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Spatial functions can now be time-dependent
+
+Tue Aug 19 09:19:33 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Sun Aug 10 18:06:39 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * check.py is distributed in the tarball
+
+Sun Aug 10 18:29:44 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Computation of maximum interface curvature is more robust
+
+Thu Aug  7 21:02:21 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * VariableFiltered is initialised
+  
+  This is important if a filtered variable is used for the initial approximate
+  projection (e.g. for the density).
+
+Tue Jul 29 09:29:57 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed left-over debugging message
+
+Mon Jul 28 09:40:22 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Sat Jul 26 12:25:31 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * gfs_init_solid_fractions() always resets the old solids first
+
+Fri Jun 20 09:28:01 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Quick fix for surfaces exactly coincident with mesh
+  
+  i.e. it should not be necessary anymore to shift implicit surfaces by epsilon 
+  to get the expected results.
+
+Thu May  1 12:09:32 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Robust treatment of border cases for gfs_line_center, gfs_plane_center
+
+Wed Jul 23 16:10:41 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Cleaner axi test case parameter file
+
+Sat Jul 26 10:44:14 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Restructured correct_normal_velocity()
+  
+  This also fixes a bug introduced by the new axisymmetric formulation.
+
+Sat Jul 26 10:43:15 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for "corner refinement" topology violation
+
+Fri Jul 25 16:01:19 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed incorrect L-dimensioning of force output
+
+Tue Jul 22 13:06:05 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric advection
+
+Tue Jul 22 12:58:42 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete charset option for html doc generation
+
+Sun Jul 20 10:38:43 NZST 2008  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Clean target for examples
+
+Sat Jul 19 13:31:26 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric Euler solver
+
+Fri Jul 18 12:38:12 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Axisymmetric potential flow around a sphere test case
+
+Sat Jul 19 13:30:19 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * L-dimensioning for OutputScalarSum, VTK and Tecplot
+
+Sat Jul 19 13:01:26 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New function "area" for interfacial area density
+
+Mon Jun  9 10:22:44 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Wave model uses user-defined length units
+
+Sun Jun  8 11:29:51 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Solid flux correction for wave model
+
+Sun Jun  8 05:16:39 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New 'garden sprinkler effect' example for wave model
+
+Fri Jul 18 22:00:35 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Several important fixes for L-dimensioning
+
+Wed Jul 16 15:10:40 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_cfl() should now take source terms into account
+
+Wed Jul 16 14:29:38 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Minor fixed to RPM spec file (I. Vari)
+
+Sat Jun  7 20:08:55 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Maximum timestep is not limited
+
+Thu Jul 10 09:43:55 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for cgd files and face boundary conditions
+
+Sun Jun  8 05:00:53 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New "Energy" derived variable for wave model
+
+Sat Jun  7 22:58:02 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsInitWave
+
+Sat Jun  7 21:35:01 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * nk and ntheta are parameters for wave model
+
+Sat Jun  7 20:10:07 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed scaling of energy for wave model
+
+Sun May 11 22:21:24 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Initial sub-cycling implementation for wave model
+
+Fri May  9 19:08:22 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Initial wave model
+
+Fri Jun 13 11:34:32 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for broken BcNavier
+
+Mon Jun  9 02:51:50 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Dimensional size of the unit box can be set
+
+Tue Jul  8 16:01:39 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Multigrid "tricks" for diffusion solver
+
+Mon Jul  7 19:03:24 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * darcs2dist puts tarballs in a tarballs/ directory
+
+Mon Jul  7 18:01:06 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed typo in RefineHeight (thanks to G. McBain)
+
+Mon Jul  7 17:59:07 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added missing gfsxref to tarball
+
+Fri Jun 20 10:44:41 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * More accurate streamlines
+  
+  Uses new function gfs_mixed_cell_interpolate().
+
+Fri Jul  4 15:20:11 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Scripts for automatic cross-reference generation
+  
+  For automatically linking keyword wiki documentation with the examples and 
+  test cases.
+
+Wed Jul  2 13:13:01 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Fri Jun 20 11:15:14 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsBoundaryGradient
+
+Tue Jul  1 16:04:32 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * RPM spec update for Fedora (I. Vari)
+
+Tue Jul  1 15:51:19 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Several fixes for GfsCartesianGrid object
+
+Fri Jun 20 21:17:25 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * darcs2dist makes tarballs with consistent version numbers
+
+Tue Jul  1 14:08:59 NZST 2008  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for doc generation with new gfs-highlight script
+
+Fri Jun 20 01:15:48 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for adaptive refinement (maxlevel was not always respected)
+
+Thu Jun 19 09:35:51 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * VariableFiltered defines values on all levels
+  
+  This should fix bugs when using a filtered variable within alpha (alpha needs 
+  to be defined on all levels for the viscous terms).
+
+Thu Jun 19 01:21:21 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious currents test case reference
+
+Fri Jun 13 00:06:05 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for linking utility libraries with libtool
+
+Wed Jun 11 21:39:58 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for OutputSimulation silly bug
+
+Wed Jun 11 00:57:31 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for VTK/Tecplot output in parallel
+
+Wed Jun 11 00:49:55 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New gfs-highlight script
+  
+  Uses GNU source-highlight for syntax highlighting of simulation files.
+
+Mon Jun  9 09:55:16 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * GfsAdaptGradient has been generalised to functions
+
+Fri May  9 19:06:54 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  UNDO: gfs_domain_add_variable() takes a class parameter
+
+Sat Jun  7 21:33:50 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * OutputSimulation really writes all the variables by default
+
+Sun May 11 22:20:44 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_event_redo()
+
+Fri May  9 19:06:54 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_add_variable() takes a class parameter
+
+Fri May  9 19:04:50 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Generalised gfs_matrix_new() to non-square matrices
+
+Sun Jun  8 20:41:49 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Checks that density is not negative
+
+Fri Jun  6 22:42:04 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for inconsistent treatment of maxlevel adaptive parameter
+  
+  This patch should ensure that cells are never more refined than maxlevel.
+
+Fri Jun  6 21:41:35 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for automake/libtool object issue
+
+Wed Apr 23 09:30:46 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  UNDO: Use dolt instead of standard libtool
+
+Tue May 13 21:34:19 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Improved options for xyz2rsurface
+
+Tue May 13 14:58:24 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Improved path system for Terrain module
+
+Tue May 13 13:12:38 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for hard-coded module names in parameter files
+
+Mon May 12 13:34:01 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New dependencies for RPM packages (I. Vari)
+
+Sat May 10 15:54:50 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * cron script uses new "devel" branches
+
+Sat May 10 15:15:48 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added cron job script in tools/
+
+Fri May  9 14:53:28 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fixed missing dependency for Terrain module
+
+Tue May  6 10:59:25 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added debian dependencies for Tide and Map modules
+
+Thu May  8 22:43:11 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * GFS_MODULES_DIR is defined in Makefile
+  
+  This should fix problems when using the --libdir option of configure
+
+Wed May  7 22:27:13 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Poiseuille flow test case
+
+Tue May  6 10:52:34 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Integrated FES2004 build within primary build
+
+Tue May  6 09:39:20 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Initial import of FES2004_distribution_soft-1.0.9
+    
+  A GPL-ed library to read FES2004 tidal atlas data.
+
+Tue May  6 09:14:02 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New derived variables rx, ry and rz
+
+Thu May  1 12:04:43 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Improved robustness of solid fraction checks
+
+Thu Apr 24 17:02:49 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New abstract class GfsGenericSurface
+
+Tue Apr 29 20:38:10 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Map module also scales z coordinate
+
+Tue Apr 29 17:00:27 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Solid boundary generation changes for Terrain module
+
+Tue Apr 29 16:58:43 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Extension of GfsRefineTerrain to 3D
+
+Tue Apr 29 13:14:58 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed "Writing new objects" section of tutorial
+  
+  This has been superseded by the wiki version in the Gerris programming course.
+
+Tue Apr 29 10:26:20 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added missing awk script in debian package
+
+Thu Apr 24 17:07:58 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Thin solid cells are flagged and "fixed" before checks
+
+Thu Apr 24 17:02:20 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New GfsTerrain class
+
+Wed Apr 23 09:31:04 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Terrain module uses R*-tree
+
+Wed Apr 23 09:30:46 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Use dolt instead of standard libtool
+
+Wed Apr 23 09:30:25 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Minor changes to RStarTree (updated header files etc...)
+
+Thu Apr 10 21:32:17 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Large file (> 2GiB) support for RStarTree
+
+Thu Apr 10 21:10:52 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Upgraded/integrated Makefile.am for RStarTree
+
+Thu Apr 10 20:32:54 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * R*-tree implementation of Norbert Beckmann
+  
+  This is the original implementation as unpacked from http://www.rtreeportal.org.
+
+Tue Apr  8 09:37:23 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * New terrain module for height-field databases
+
+Tue Apr  1 14:39:32 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New module for FES2004 tidal boundary conditions
+
+Tue Apr  1 13:14:15 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * GModule can take parameters
+
+Fri Mar 28 15:26:35 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New Map module for cartographic projections
+
+Tue Mar 25 16:57:21 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Support for geometric "mapping" of domain coordinates
+
+Wed Jan 30 11:31:34 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Single-layer ocean model can now use "3D" code rather than "2D3"
+
+Fri Apr 18 12:12:37 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Stricter checking when compiling user-defined GfsFunctions
+
+Fri Apr 18 12:07:41 NZST 2008  Stephane Popinet <popinet at users.sf.net>
+  * Need to make sure that all PEs use the same timestep!
+  
+  Important bug fix for the parallel version.
+
+Sat Apr  5 16:10:34 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Check for unclosed statement in parameter files
+
+Tue Mar 25 11:35:46 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Checks that variable names are not reserved keywords
+
+Tue Mar 18 12:49:03 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Examples files are distributed only if they are version-controlled
+
+Thu Mar 13 12:25:11 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed MRS acceleration
+  
+  While this accelerated convergence somewhat in some cases, it seemed to prevent
+  convergence in other cases. This patch is not an exact "rollback" of the
+  initial MRS implementation because it does not rollback other simple but 
+  important changes to the Poisson solver which seem to really improve robustness.
+
+Thu Mar 13 10:54:50 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for MRS implementation in parallel
+
+Tue Mar 11 16:20:04 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Minimal Residual Smoothing implementation
+  
+  This guarantees that the Poisson solver does not diverge (but does not
+  guarantee convergence). It can also accelerate convergence depending on the
+  problem. Coupled with other smaller changes included in this patch ('minlevel'
+  tuning in particular) this improves the robustness of the solver.
+
+Wed Mar 12 15:41:31 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Series 60 ship waves example
+
+Mon Mar 10 19:39:25 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * SourceControl was broken by momentum source term patch
+
+Fri Mar  7 11:31:24 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * 'omega' relaxation parameter is written only if different from default
+  
+  This means that simulation files are backward-compatible with older versions of
+  gerris/gfsview. 
+
+Thu Mar  6 20:29:16 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for sign error in new momentum source term implementation
+
+Thu Mar  6 13:22:02 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * GfsOutput pipes now know the pre-defined Gerris shell variables
+
+Thu Mar  6 09:41:40 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * gerris.spec version number fix
+
+Wed Mar  5 15:51:18 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Optimised temporary variables usage for "gc" option
+
+Wed Mar  5 14:41:38 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Cosmetics
+
+Wed Mar  5 12:55:54 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed generation of Postscript docs
+
+Tue Mar  4 17:11:27 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for VOF patch introducing "_x", "_y" and "_alpha" variables
+
+Fri Feb 29 12:34:18 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * VOF interface normals and alpha values are named variables
+  
+  e.g. for a VOF tracer called "T" in 2D, three new variables are automatically 
+  created "T_x", "T_y" and "T_alpha".
+
+Tue Mar  4 15:05:43 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * GfsSource terms for velocity components are consistent with projection
+  
+  i.e. they are computed in a manner consistent with the pressure gradient 
+  discretisation (in a manner similar to the surface tension). This is necessary
+  in particular to guarantee exact hydrostatic balance with non-linear pressure
+  distributions (e.g. the 'hydrostatic/quadratic' test case).
+
+Thu Oct 18 17:30:51 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added stability conditions for SourceDiffusionExplicit and SourceViscosityExplicit
+
+Tue Mar  4 13:35:16 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New quadratic hydrostatic pressure test case
+
+Fri Feb 29 11:27:04 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for OutputDropletSums when using functions as volume fraction
+
+Wed Feb 27 12:03:50 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New air/water capillary wave test case
+
+Wed Feb 27 11:20:27 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases for surface tension/advection bug fix
+
+Wed Feb 27 10:32:11 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Pressure-correction in the Crank-Nicholson scheme is turned off by default
+  
+  This was degrading the results for a number of test cases (capillary waves in
+  particular). The reasons why are still unclear.
+  
+  Note that this does not mean that this version of the code is the same as the
+  version prior to the "Pressure term is included in RHS of viscosity solve"
+  patch, as this version also includes an important bug fix for the advection
+  terms when surface tension is present.
+  
+  The pressure-correction Crank-Nicholson scheme can be turned off explicitly 
+  when required (e.g. "hydrostatic" test case).
+
+Fri Feb 22 12:28:45 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Cleanup of GfsEventScript temporary files handling
+
+Fri Feb 22 10:35:36 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Pressure term is included in RHS of viscosity solve
+  
+  This is an important change to the timestepping which should improve
+  things significantly in particular when large source terms are included
+  (e.g gravity + hydrostatic pressure).
+
+Fri Feb 22 10:01:09 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for initial timestep in Boussinesq example
+
+Tue Jan 22 11:32:56 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New 'hydrostatic' test case
+
+Thu Feb 21 16:55:57 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix when restarting simulations using SurfaceBc
+
+Thu Feb 21 11:48:23 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fixes for VTK/Tecplot output
+
+Wed Jan 30 09:51:03 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Added 'omega' over-relaxation parameter
+
+Fri Jan 25 15:24:16 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Removed gfs_get_from_below_extensive
+
+Wed Jan 16 14:53:41 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * GfsInit becomes a standard GfsEvent when either step or istep is specified 
+
+Mon Feb 11 18:36:08 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * VTK/Tecplot export
+
+Tue Jan 29 16:13:06 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Improved robustness of checks for 'beta' and 'waves' test cases
+
+Wed Jan 16 17:36:38 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix when using multiple GfsTime objects in parameter files
+
+Wed Jan 16 10:52:23 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Various 'fixme' comments
+
+Wed Jan 16 10:07:47 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New "dV" intrinsic domain variable
+
+Wed Jan 16 10:04:54 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Renamed GfsOutputDropletStats to GfsOutputDropletSums
+  
+  Note that the syntax has changed, please check the doc.
+
+Wed Jan 16 10:04:24 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated gfs_domain_remove_droplets() to use new GFS_VALUE macro
+  
+  Eventually this macro will replace GFS_VARIABLE.
+
+Wed Jan 16 09:55:55 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * RemoveDroplets takes an extra optional argument
+  
+  Which allows flexible selection of the "droplet" criterion.
+
+Tue Jan 15 13:12:36 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Force reference of domain in Variable and DerivedVariable
+
+Mon Jan 14 17:13:25 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Fix for missing variable descriptions
+
+Sun Jan 13 21:09:06 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Deferred GfsFunction compilation
+  
+  Optionally, GfsFunctions are compiled only when they are used for the first
+  time. This greatly improves the speed of GfsView when reading input piped from
+  Gerris (when the simulation contains one or several GfsFunctions).
+
+Sun Jan 13 16:36:05 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Sat Jan 12 18:52:58 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Timestep is set properly to guarantee CFL condition
+  
+  This should fix CFL problems when using the VOF scheme.
+
+Fri Jan 11 15:00:23 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsOutputDropletStats
+
+Fri Jan 11 13:48:15 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_domain_tag_droplets()
+  
+  Used by GfsRemoveDroplets. This is more generic than the previous 
+  implementation.
+
+Fri Jan 11 12:10:30 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * New intersection, union and difference predefined macros
+
+Thu Jan 10 13:10:48 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * 'error.gfs' dump files are indexed by PE number
+
+Thu Jan 10 12:20:30 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * Stricter syntax checking for read() method of Domain
+
+Tue Jan  8 09:46:09 NZDT 2008  Stephane Popinet <popinet at users.sf.net>
+  * RPM build fix (I. Vari)
+  
+  Removed %{?_smp_mflags} from make due to intermittent
+  build errors on some SMP systems.
+
+Fri Dec 21 14:53:02 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_cfl takes MAC velocities into account
+
+Thu Dec 20 23:45:56 NZDT 2007  Daniel Fuster <dfuster at gmail.com>
+  * gfsjoin201207
+  Gfsjoin bug: fixed
+
+Wed Dec 19 17:44:14 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New Cook Strait tides example
+
+Tue Dec 18 15:54:36 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Simplified regular expression in m4.awk
+  
+  Hopefully this will fix issues with POSIX regex etc...
+
+Thu Dec  6 09:42:42 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated debian package dependencies
+  
+  This should fix problems with recent Ubuntu versions (>= 7.10).
+
+Wed Dec  5 09:28:46 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for reading VariablePosition reference position
+
+Thu Nov 15 16:24:59 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * In VOF advection GfsAdvectionParams needs to be initialised properly
+
+Mon Nov 12 14:59:18 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * VOF advection should now work also with embedded solid boundaries
+
+Mon Nov 12 15:47:16 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed package (install) dependencies
+
+Mon Nov 12 09:20:19 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for refinement of coarse VOF cells in parallel
+  
+  Thanks to Daniel Fuster for reporting the problem.
+
+Fri Nov  9 11:09:44 NZDT 2007  dfuster at gmail.com
+  * gfsjoin1108
+  Some modifications are introduced to fix some problems which could appear with the older version
+  Checking options are added
+  Minor format changes
+
+Fri Nov  9 17:34:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * cell_init() is now a method of GfsDomain
+  
+  This simplifies applying a consistent initialisation when creating
+  children cells, in particular for the complicated initialisation
+  occuring when refining interface cells between direction-sweeps during
+  VOF advection.
+
+Tue Nov  6 12:56:45 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New script gfsjoin (written by Daniel Fuster)
+
+Thu Nov  1 08:38:24 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for "classes" internal utility with MPI
+
+Tue Oct 30 15:52:48 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added spec file for RPM packaging (thanks to Ivan Vari)
+
+Tue Oct 30 14:46:10 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for MPI version of gfs_domain_stats_balance()
+
+Wed Oct 24 11:26:43 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Boundary conditions are applied within Init events
+  
+  This is necessary e.g. when subsequent variables are derived from the gradients
+  of previously initialised variables.
+
+Tue Oct 23 10:52:25 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Minimised round-off errors in face_fractions()
+
+Mon Oct 15 12:08:37 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated waves test case references
+
+Fri Oct 12 17:10:33 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_domain_boundary_locate()
+  
+  This is important only for VOF boundary conditions.
+
+Fri Oct 12 11:45:47 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Improved secant-bisection root-finding for implicit surfaces
+
+Wed Oct 10 13:57:32 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Refines cells which are too coarse for VOF advection
+  
+  Cells are too coarse when one of their neighboring cells is finer and
+  contains and interface which will be advected in them at the next
+  timestep.
+
+Thu Oct 11 12:50:12 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New pre-defined implicit surface 'cube'
+
+Thu Oct 11 11:37:41 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Both GfsRefineSolid and GfsRefineSurface now work with implicit surfaces
+
+Wed Oct 10 12:06:14 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New 'cfactor' parameter for GfsAdapt
+
+Tue Oct  9 13:45:45 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_domain_reshape()
+  
+  Quoting the doc: 
+  "Force the grading of the tree hierarchy of domain, matches the
+  boundaries, recomputes merged cells and applies the boundary
+  conditions for all variables."
+
+Fri Sep 28 16:05:17 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * gfs_cell_is_cut() is more clever when dealing with implicit surfaces
+  
+  This means in particular that GfsRefineSurface now also works with implicit 
+  surfaces.
+
+Fri Oct  5 15:42:04 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for compatibility with glib-1.2 series
+
+Wed Oct  3 09:48:45 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Miscellaneous doc/comments fixes
+
+Fri Sep 28 16:18:23 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsNorm ignores values with a weight of zero for max norm
+
+Fri Sep 28 15:07:18 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for text macros within comments
+
+Fri Sep 28 14:59:13 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New "w" option for GfsOutputErrorNorm
+
+Thu Sep 20 12:05:00 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed incorrect label for capillary wave test case
+
+Tue Sep 18 12:26:19 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added figure to capillary wave test case
+
+Tue Sep 18 10:48:09 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated Poisson test cases references
+  
+  The errors have been increased somewhat by using the more robust
+  gradient_fine_coarse() implementation.
+
+Tue Sep 18 10:23:11 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Improved formatting of test suite doc header
+
+Tue Sep 18 10:04:51 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_domain_stats_balance() on serial parameter files
+
+Tue Sep 18 09:58:32 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete installation instructions from the tutorial
+
+Fri Sep 14 13:28:16 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New option 'data' for gerris (when splitting or partitioning)
+
+Fri Sep 14 13:24:18 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * OutputBalance takes "pid" into account even for non-parallel simulations
+
+Fri Sep 14 11:39:03 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed gfsview parameters for Boussinesq example
+
+Fri Sep 14 11:07:59 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for domain splitting with periodic boundary conditions
+
+Fri Sep 14 10:10:22 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Domain traversal should now be deterministic
+  
+  ...as well as the rest of Gerris. This was not the case before because of the
+  "randomization" effect of using hash tables indexed on pointers to store the
+  graph nodes (i.e. the GfsBoxes). This was a pain for debugging and also caused
+  boxes to "jump around" when visualising periodic domains with several boxes.
+
+Thu Sep 13 15:01:21 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New "Id" and "Pid" derived variables
+
+Thu Sep 13 09:53:12 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added clock start/stop to avoid harmless warnings
+
+Thu Sep 13 09:41:44 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Error message when trying to partition a domain composed of too few boxes
+
+Wed Sep 12 16:36:43 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for bad comment indentation in parameter files views
+
+Tue Sep 11 15:42:39 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for SourceControl divide by zero
+
+Fri Sep  7 16:33:50 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Minor maintenance (comments, valgrind stuff etc...)
+
+Sun Sep  9 09:46:51 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Automake 1.6 is OK (I guess 1.4 is not)
+
+Sat Sep  8 18:09:40 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed boundary conditions for boussinesq example
+  
+  As pointed out by Phil Rubini, the previous boundary conditions were 
+  misleading: they were equivalent to flow in a closed box rather than the
+  expected vertical open channel.
+
+Sat Sep  8 15:11:44 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed typo in oscillation.gfs
+
+Fri Sep  7 16:27:34 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Fri Sep  7 13:12:54 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Test cases are run in the order they appear in the final report
+
+Fri Sep  7 12:04:09 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added 'Define' to known classes
+
+Fri Sep  7 11:33:20 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed formatting of gfs2tex parameter file view
+
+Fri Sep  7 10:57:16 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for uninitialised normal z-component in parabola_fit_init()
+  
+  ..or how 4 characters can lead to no end of trouble...
+
+Thu Sep  6 16:48:35 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Macro support needs to be turned on explicitly
+  
+  To avoid m4 problems when trying to apply macros to 
+  binary simulation files.
+
+Thu Sep  6 14:07:39 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for plotting style of reynolds test case
+
+Thu Sep  6 14:05:28 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New inviscid droplet oscillation test case
+
+Wed Sep  5 18:07:29 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious and capwave test cases
+
+Wed Sep  5 13:27:01 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * 'kinetic' test case uses a mollified volume fraction
+
+Wed Sep  5 12:30:59 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Macro support in parameter files
+
+Wed Sep  5 12:09:45 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Checks that automake version is >= 1.8
+
+Wed Sep  5 12:09:04 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added assertions alpha > 0.
+  
+  Alpha (1/rho) is user defined and could take negative values if care is not
+  taken.
+
+Thu Aug 30 14:08:31 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * gradient_fine_coarse() uses only directly neighbouring cells
+  
+  Using a third cell in the opposite direction, although nominally second-order
+  in space could cause instabilities. The reduced spatial order of this new
+  implementation does not seem to affect the convergence rates for the test cases
+  in the test suite.
+
+Mon Sep  3 15:36:26 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Dependency fix for order of variables when writing simulation files
+  
+  Physical parameters can depend on defined variables. The incorrect order
+  could prevent from restarting a simulation.
+
+Fri Aug 31 18:31:16 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Initial projection is skipped when restarting a simulation
+
+Fri Aug 31 14:42:54 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Constants can be expressions (not for all objects yet)
+
+Sun Aug 19 12:19:48 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * VariableFiltered was not taking the number of iterations into account
+
+Thu Aug 30 13:18:34 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated CSS stylesheet for consistency with wiki
+
+Wed Aug 29 11:33:14 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for adaptation with 'maxcells' set
+
+Wed Aug 29 10:59:38 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for memory corruption when trying to do "twisted" streamlines in 2D
+
+Wed Aug 22 12:58:07 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Major bug fix for VOF advection scheme
+  
+  The previous implementation did not take into account properly the
+  compression/expansion of cell volumes at each step of the split
+  scheme. As a result the overall scheme had very poor mass
+  conservation.
+
+Tue Jul 24 09:50:32 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New test case for kinetic energy conservation in multiphase flows
+
+Thu May 24 15:10:02 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  UNDO: Refines cells which are too coarse for VOF advection
+  
+  Cells are too coarse when one of their neighboring cells is finer and
+  contains and interface which will be advected in them at the next
+  timestep.
+
+Thu May 24 15:10:02 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Refines cells which are too coarse for VOF advection
+  
+  Cells are too coarse when one of their neighboring cells is finer and
+  contains and interface which will be advected in them at the next
+  timestep.
+
+Wed Aug 22 16:14:41 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious currents test case
+
+Wed Aug 22 15:26:02 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated 'shear' VOF advection test case
+  
+  Including test for mass conservation.
+
+Wed Aug 22 15:25:07 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New VOF advection test case with adaptive refinement
+
+Wed Aug 22 12:43:09 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Ignore white spaces at the start of a parameter file
+
+Wed May 30 14:53:30 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Capillary wave test case uses a larger domain aspect ratio
+  
+  This improves the convergence significantly and the results
+  compare well with those of Gerlach et al (added in the biblio).
+
+Wed May 23 16:36:26 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Face curvature does not use vof-weighted averaging anymore
+
+Wed Aug 15 17:06:45 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Automated darcs versioning ignores changes in the doc/ directory
+
+Fri May 25 12:28:28 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Kmax values for "nearly empty" interfacial cells are filtered
+
+Wed May 23 12:41:23 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature optionally computes the maximum curvature
+
+Tue May 22 13:28:48 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Cleanup of HF curvature calculation
+
+Tue May 22 10:53:44 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Several improvements to height-function curvature calculation
+  
+  - Interface positions are taken into account only if they are far enough apart.
+  - Nearest neighbour interpolation is used before resorting to facet-fitting.
+  - Various options for circle-fitting and paraboloids of different degrees etc...
+
+Thu May 10 11:59:46 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Paraboloid fitting for curvature calculation in 3D
+
+Sat May  5 13:53:43 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Parabola fitting uses normal direction and local interface position
+
+Thu May  3 09:43:42 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Parabola fitting for gfs_height_curvature()
+
+Mon Apr 30 22:15:19 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * More robust implementation of gfs_height_curvature()
+  
+  Tries all directions of integration (based on normal orientation) rather than
+  only the first guess.
+
+Sun Aug 12 19:31:36 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for ffmpeg options and mktemp in ppm2mpeg
+  
+  Newer ffmpeg versions seem to have stricter syntax for the bitrate.
+  
+  Also mktemp does not seem to accept the "-t" option on all systems.
+
+Sat Jul 28 19:26:30 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * BcNavier for Navier slip condition
+
+Thu Jul 26 14:02:05 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Explicit message when trying to use implicit surfaces with RefineSolid
+
+Tue Aug  7 17:06:21 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed comment formatting for logo example
+
+Tue Aug  7 17:03:38 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Testing framework now depends on bash
+  
+  So that we can use the "set -o pipefail" option to be sure to capture all
+  errors when running a test command which is made of independent piped 
+  commands (e.g. "gerris2D logo.gfs | gfsview2D logo.gfv").
+
+Thu Aug  2 15:32:28 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Improved error checking for ppm2mpeg
+
+Fri Jul  6 00:58:23 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for corner case in face_bilinear()
+
+Sat Jun  9 22:05:22 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsSourceViscosityExplicit
+
+Wed May 23 14:42:52 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for marginal case in myc (3D version)
+
+Wed May 23 11:18:42 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsFunction does not use variable index anymore
+  
+  The index of a variable can vary during the simulation. Use the
+  variable's address instead.
+
+Tue May 22 10:53:05 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for degenerate case in gfs_domain_remove_droplets
+
+Sun May 20 21:51:55 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * G_MAXDOUBLE values are ignored by gfs_norm_add() and gts_range_add_value()
+
+Fri Apr 27 10:35:25 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for inconsistent momentum diffusion
+  
+  When using SourceDiffusion for variable density flows
+  (thanks to Shahriar Afkhami for reporting this).
+
+Fri Apr 27 09:58:03 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New exported function gfs_multilevel_params_stats_write()
+
+Thu Apr 26 12:57:34 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Reformatted bibtex reference
+
+Wed Apr 25 10:21:24 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * More detailed versioning of test cases summary
+
+Wed Apr 25 10:15:42 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsSurface transformations
+
+Tue Apr 24 19:09:50 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Moved 'shear' example to test cases
+
+Tue Apr 24 13:35:07 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for gfs2doc when used on test cases
+
+Tue Apr 24 13:02:06 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated examples to use implicit surfaces
+
+Tue Apr 24 12:56:18 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Configure checks for linker flags required for module compilation
+  
+  This should fix issues on the various versions of Mac OSX.
+
+Tue Apr 24 18:48:25 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Rotations for GfsSurface are defined only via principal axis
+
+Tue Apr 24 11:09:40 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for Fedora tarball
+
+Mon Apr 23 19:10:49 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Minor bug fixes
+
+Fri Apr 20 17:47:10 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for expression parsing
+
+Fri Apr 20 17:35:50 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated wave tests to use implicit surfaces
+
+Fri Apr 20 16:53:56 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_surface_segment_normal()
+
+Fri Apr 20 16:53:29 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New predefined spatial function 'sphere()'
+
+Fri Apr 20 15:44:55 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated tests with new implicit surfaces
+
+Fri Apr 20 15:44:00 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for "flattened" surfaces in RefineSurface
+
+Fri Apr 20 13:45:51 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Secant/bisection root-finding for implicit surfaces
+
+Wed Apr 18 17:39:26 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Solid boundaries can be defined using implicit surfaces
+  
+  # a cylinder of radius 0.0625
+  Solid (x*x + y*y - 0.0625*0.0625)
+  
+  This can also be used to define volume fractions (using GfsInitFraction).
+
+Fri Apr 20 10:28:39 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Docs are not included in the distribution tarball anymore
+
+Tue Apr 17 12:17:48 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * All surfaces are now defined using a new GfsSurface object
+  
+  Note that this is a new object, the previous "GfsSurface" has been replaced with
+  "GfsSolid".
+
+Mon Apr 16 11:29:55 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Detailed versioning based on darcs
+
+Mon Apr 16 11:08:28 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * darcs2dist checks that the tarball builds properly
+
+Mon Apr 16 11:07:10 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added missing desktop files to tarball distribution
+
+Fri Apr 13 17:56:32 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsSurface allows transformations of the input GTS surface
+
+Fri Apr 13 17:46:36 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New GfsSurface class replaces GtsSurfaceFile and GtsSurface
+  
+  The GtsSurfaceFile keyword is still supported, however the GtsSurface keyword is
+  not and should be replaced by "GfsSurface {}" in old simulation files.
+
+Fri Apr 13 14:00:20 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New tool gfs2gfs to convert old simulations to the current format
+
+Fri Apr 13 13:00:37 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * First parameter block of GfsEvent is now optional
+  
+  Provided it is not followed by another parameter block.
+
+Thu Apr 12 14:33:04 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * curvature_coarse_fine() did not work when using a VariableDistance
+
+Thu Apr 12 12:02:04 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Simplified layered (2D3) GfsOcean implementation
+  
+  A first step towards a full 3D (non-layered) ocean model.
+  
+  Note that variables "HU" and "HV" are no longer defined. "U" and "V"
+  should be used instead (particularly for Flather BCs in parameter
+  files).
+
+Thu Apr 12 11:42:54 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated nz test case
+
+Thu Apr 12 10:08:55 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated circle/refined test case for new fine/coarse gradient calculation
+
+Wed Apr 11 17:23:17 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Changed fine_coarse gradient calculation
+  
+  Fine cells on the left-hand-side of the fine-coarse boundary are taken
+  into account only if they are not mixed. This is to ensure the
+  stability of the GfsOcean model (the nz test case).
+
+Wed Apr 11 17:20:53 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New adaptive coastally-trapped wave test case
+
+Wed Apr 11 17:19:25 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New gravity waves in Cook strait test case
+
+Thu Apr  5 13:45:14 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Simplified Poisson coefficients calculation
+
+Thu Mar 29 12:45:42 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for gfs_domain_traverse_cut_2D()
+
+Thu Mar 29 11:20:41 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Merged advection fluxes redistribution is done differently
+  
+  This mitigates the appearance of negative values for positive tracers near
+  solid boundaries.
+
+Tue Mar 27 16:16:21 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for non-initialised fractions in GfsOcean
+
+Tue Mar 27 12:24:42 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New derived variables for surface fractions
+
+Tue Mar 27 12:23:04 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Adaptivity along solid boundaries should now work (but not for 2D3 yet)
+
+Fri Mar 23 09:28:08 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added check for positiveness of solid->s[0]
+
+Fri Mar 23 09:16:55 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * ftt_cell_locate() works for 2D3
+
+Tue Mar 20 13:06:56 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  UNDO: Source terms for non-advected variables are taken into account
+
+Tue Mar 20 13:06:56 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Source terms for non-advected variables are taken into account
+
+Tue Mar 20 12:57:58 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Improved error messages for Cartesian grid interpolation
+
+Mon Mar 19 12:39:13 NZST 2007  Cedric Penard <cedric.penard at ifremer.fr>
+  * Cartesian functions
+
+Mon Mar 19 17:07:37 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * gfs_plane_center() works with any normal
+  
+  Not just with normals in the positive quadrant.
+
+Mon Mar 19 17:05:45 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * New functions gfs_vof_plane_facet() and gfs_vof_plane_center()
+
+Sun Mar 18 12:18:19 NZST 2007  Stephane Popinet <popinet at users.sf.net>
+  * Simplified circular wave test case (using GfsGlobal)
+
+Fri Mar 16 17:13:03 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * "Permanent" cells cannot be coarsened
+  
+  At the moment this is used to prevent coarsening of the initial
+  embedded solid surface: a first step towards adaptivity of embedded
+  solid surfaces.
+
+Fri Mar 16 15:03:01 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Special 2D3 case for interpolate_1D1 upwinding
+
+Fri Mar 16 14:32:20 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Initial timestep is set to zero (not one)
+
+Fri Mar 16 14:31:31 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Small fix for GfsCartesianGrid
+
+Thu Mar 15 16:14:21 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New "twod" option for GfsRefineSurface
+
+Thu Mar 15 11:51:11 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Merged cells work for 2D3
+
+Thu Mar 15 11:47:58 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Small cells cannot be close to boundaries
+
+Thu Mar 15 11:03:13 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New derived variable "dt" (timestep)
+
+Wed Mar 14 17:21:29 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsOcean uses new variables "HU" and "HV" to store the barotropic velocity field
+  
+  This simplifies the implementation of Flather boundary conditions.
+
+Tue Mar 13 16:18:40 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Cleanup of GfsCartesianGrid
+
+Tue Mar 13 15:45:54 NZDT 2007  Cedric Penard <cedric.penard at ifremer.fr>
+  * Fix for merge with stable branch
+
+Tue Mar 13 14:01:28 NZDT 2007  C[_\c3_][_\a9_]dric P[_\c3_][_\a9_]nard <cedric.penard at ifremer.fr>
+  * New object GfsCartesianGrid
+
+Tue Mar 13 15:25:43 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated couette.gfs
+  
+  Comments in functions must now use the C format ('/*' not '#').
+
+Fri Mar  9 16:37:42 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Further bug fixing for comments in GfsFunction expressions
+
+Fri Mar  9 10:00:43 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated examples doc
+
+Thu Mar  8 16:54:54 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for Dirichlet BC for VOF tracers
+
+Thu Mar  8 10:04:53 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsVariablePosition takes an optional 'ref' argument
+
+Mon Mar  5 11:45:42 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated Rayleigh-Taylor example
+
+Sun Mar  4 21:03:24 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for reseting 'status' when computing solid fractions
+
+Sun Mar  4 21:02:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Init events are turned into standard events when specifying 'step'
+
+Sun Mar  4 21:01:33 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated shear example
+
+Sat Dec  2 19:33:35 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  UNDO: Init events are also realised at half timesteps
+
+Fri Mar  2 14:51:18 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed dependencies for gfsclasses.py
+
+Fri Mar  2 14:33:12 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Cleanup of Couette flow test case
+
+Fri Mar  2 14:29:57 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for face interpolation of diffusion coefficients
+
+Fri Mar  2 14:25:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Unified script/code treatment for GfsGlobal, GfsEventScript and GfsOutput
+  
+  This fixes a bug in GfsOutput and GfsEventScript where "#!" were
+  treated as comments.
+
+Fri Mar  2 09:14:32 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Debian package recommends various bits and bobs
+
+Fri Mar  2 09:10:36 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated surface tension test cases
+
+Fri Mar  2 16:42:49 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added Gerris logo example
+
+Thu Mar  1 16:53:23 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed face_bc() for GfsBcDirichlet
+
+Thu Mar  1 09:54:14 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * VOF normal is computed using "myc" in 2D (thanks to Ruben Scardovelli)
+
+Wed Feb 28 16:33:59 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases
+
+Wed Feb 28 16:32:00 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Temporary bug fix for GfsEventStop
+  
+  For more "complex" variables (e.g. VariableTracerVOF) EventStop will
+  not work properly if adaptivity is used. There is no simple solution
+  to this problem.
+
+Wed Feb 28 16:29:55 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added icons for mime types
+
+Tue Feb 27 15:15:31 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for merge with CSF branch
+
+Tue Feb 27 14:59:13 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added tolerance to avoid "missed" synchronised events
+
+Tue Feb 27 14:56:33 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for overflow exception
+
+Thu Feb 22 10:34:27 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated gfs_classes()
+
+Mon Feb 12 14:46:56 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Mixed Youngs-Centered VOF normal calculation
+
+Fri Feb  9 17:24:41 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Symmetry boundary conditions for VOF
+  
+  These are approximate only, in particular the boundary conditions for
+  the normal should be anti-symmetric not symmetric (as implemented in
+  this patch). The effect of this approximation should be small however.
+  
+  Also, not sure what the symmetry conditions actually do when combined
+  with complex solid boundaries.
+
+Fri Feb  9 13:54:16 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for periodic boundary conditions
+
+Wed Feb  7 17:00:23 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for small VOF fragments in vof_fine_coarse()
+
+Wed Jan 31 11:42:48 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Simplified and more robust Youngs stencil routine
+
+Tue Jan 30 16:59:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete AdaptNotBox stuff
+
+Sun Jan 28 21:02:01 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * VOF Tracers are now defined using GfsVariableTracerVOF
+  
+  Normal directions and alpha are pre-computed and stored together with the VOF 
+  fraction.
+
+Sat Jan 27 10:33:46 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Stability criterion for gravity waves only takes into account interface cells
+
+Mon Dec 11 14:54:57 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature uses either height-function method or levelset
+  
+  According to the arguments (i.e. the second argument specifies a 
+  VariableTracer or a VariableDistance).
+
+Wed Dec  6 15:32:16 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsVariablePosition
+  
+  For implementation of "reduced gravity".
+
+Sun Aug 13 19:34:40 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Periodic boundary conditions do not use connectivity
+  
+  This made calculating geometric relationships difficult (e.g. distance between
+  cells etc...). Periodic links are now automatically replaced by a new type of
+  boundary condition (GfsBoundaryPeriodic). This is also used as a base class 
+  for a simplified GfsBoundaryMPI implementation.
+  
+  This should fix the bug when using the diffusion solver with embedded solid 
+  boundaries combined with periodic boundary conditions.
+
+Mon Aug 14 11:55:46 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_domain_filter()
+
+Sat Apr 22 14:07:37 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsEventSumDirection
+
+Thu Feb 22 10:44:09 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * gfs_simulation_adapt() does not take a "stats" parameter anymore
+
+Tue Feb 13 16:22:44 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Removed warning for interpolation of GTS files in functions
+
+Thu Feb  1 10:27:33 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Merged advection fluxes were not correctly weighted
+  
+  For solid boundaries with a variable resolution.
+
+Sun Jan 28 21:11:17 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated SourceTensionCSS to reflect new staggered timestepping of tracers
+
+Sun Jan 28 20:52:57 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Initialisation of simulation is done using gfs_simulation_init()
+
+Sun Jan 21 18:48:29 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Optimised implementation of ftt_cell_locate()
+
+Sat Dec  2 19:33:35 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Init events are also realised at half timesteps
+
+Fri Jan 19 16:53:31 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * VOF works (as in "does not crash") with embedded solid boundaries
+
+Fri Jan 19 10:42:07 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New gravity wave test case
+
+Fri Jan 19 09:32:43 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated capillary wave test cases
+
+Fri Jan 19 09:28:36 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Tracers are now defined at time n+1/2
+  
+  The resulting "leap-frog" time integration allows to recover second-order 
+  accuracy for variable-density and surface-tension-driven flows.
+
+Thu Jan 18 10:47:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for face coordinates calculation in GfsFunction
+
+Fri Dec 22 17:19:58 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New test case for capillary wave with fluids of different densities
+
+Tue Dec 19 08:54:38 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * gfs_vof_facet() could fail for degenerate cases
+
+Tue Dec 19 08:52:43 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Changed the format used by gfs_write_mac_velocity() to gnuplot
+
+Tue Dec 19 08:48:40 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Default CFL for VOF advection has been set to 0.45
+  
+  To have some margin. Also a warning has been added in case the true
+  CFL is larger than 0.5 (when doing the VOF advection proper).
+
+Thu Dec 14 14:30:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Density (and viscosity) is computed using face-interpolated volume fraction values
+  
+  This uses the new gfs_function_face_value(). Large density ratio flows
+  can now be computed correctly. Needs further testing.
+
+Thu Dec 14 16:19:10 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated Rayleigh-Taylor example
+  
+  Now it really works, thanks to the new density calculation. The results
+  compare well to other simulations (Surfer and Marker code results in my
+  thesis).
+
+Thu Dec 14 13:03:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * gfs_function_face_value() uses the face-interpolated values of variables
+
+Mon Dec 11 15:22:30 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added description for VariableDistance
+
+Mon Dec 11 15:03:53 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed constant for stability constraint of surface tension
+
+Wed Dec  6 13:20:18 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Functions to compute cell/plane intersections have been moved from GfsView
+  
+  They are used to compute 3D VOF facets.
+  Note also that the interface of gfs_vof_facet() has changed.
+
+Tue Dec  5 12:26:07 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * "Non-hydrostatic pressure" implementation
+  
+  This is useful for two-phase flows with a (flattish) interface, variable 
+  density and gravity. The hydrostatic pressure is substracted off and the 
+  remaining pressure jump across the interface due to gravity is discretised 
+  using the same technique as for surface tension. This guarantees an accurate 
+  solution free of spurious (gravity) currents.
+
+Fri Dec  1 15:35:09 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for VOF boundary conditions
+
+Tue Nov 28 12:30:19 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VOF plane is defined in full cells
+  
+  This prevents floating point exceptions when assigning undefined values to VOF
+  plane variables.
+
+Tue Nov 28 12:28:36 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Code cleanup for tension coefficients
+
+Tue Nov 28 12:24:16 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Generic boundary conditions cannot be applied for VOF fractions
+  
+  A special case treatment has been added for symmetry and Dirichlet conditions.
+
+Fri Nov 24 16:13:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Multiple SourceTension terms are permitted
+  
+  For example a combination of surface tension and "reduced gravity".
+
+Thu Nov 23 14:56:30 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * SourceTension can be used to implement "reduced gravity"
+
+Thu Nov 23 10:54:20 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Maximum CFL is 0.5 for VOF
+
+Tue Nov  7 18:54:44 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * More robust algorithm for computation of local interface height
+
+Fri Nov  3 17:31:30 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Height-Function curvature calculation should now work in 3D
+  
+  and also on 3D adaptive grids.
+
+Fri Nov  3 13:26:59 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Limit on the size of the HF-curvature calculation "stencil"
+
+Thu Nov  2 17:27:08 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * 3D implementation of gfs_youngs_normal()
+
+Thu Nov  2 17:25:01 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * "Exact" implementation of gfs_plane_alpha() in 3D
+  
+  This replaces the Newton iterations version. It is much more accurate and
+  hence ensures better volume conservation.
+
+Thu Nov  2 11:39:24 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Singular 3D VOF volume calculations use the 2D algorithm
+  
+  This guarantees exact volume representation.
+
+Wed Nov  1 15:24:50 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for VOF advection with periodic boundary conditions
+
+Mon Oct 23 18:00:48 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added missing variable descriptions
+
+Sun Oct 22 22:06:34 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Important bug fix for boundary conditions on alpha
+
+Sat Oct 21 17:58:40 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed VOF-plane calculation for isolated interface fragments
+  
+  The zero-norm of the singular interface normal in this case was causing NaN
+  problems.
+
+Fri Oct 20 17:00:04 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed VOF advection boundary conditions
+
+Fri Oct 20 16:59:51 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Capillary wave test case took too long to run with 7 levels
+
+Fri Oct 20 14:40:04 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Figure for PLIC height calculation
+
+Fri Oct 20 14:39:50 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious currents test case
+
+Thu Oct 19 17:16:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added warnings when HF-curvature fails
+
+Thu Oct 19 17:16:12 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * SourceTension and SourceTensionCSS are derived from a new SourceTensionGeneric object
+  
+  Also SourceTensionCSS "works" again thanks to the new function 
+  gfs_youngs_gradient (actually a renamed version of the old 
+  gfs_youngs_normal implementation).
+
+Wed Oct 18 17:27:32 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * GfsSourceTension takes an extra 'sigma' argument
+
+Wed Oct 18 17:02:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated capillary wave test case
+
+Wed Oct 18 16:58:11 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Cleanup of HF-curvature implementation
+
+Wed Oct 18 11:50:16 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * HF curvature calculation works on adaptive meshes!
+  
+  But in 2D only for the moment. This patch also contains various (unused) 
+  routines implementing other ways of computing the curvature (based on VOF 
+  interface reconstructions, mean-square parabola and circle fit  etc...)
+
+Sun Oct  8 21:26:16 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_vof_interpolate()
+
+Fri Oct  6 15:09:51 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New functions gfs_fit_curvature() and gfs_shahriar_curvature()
+
+Fri Oct  6 15:07:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_domain_boundary_locate()
+
+Tue Aug 15 21:44:55 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature uses height method rather than levelset
+
+Tue Aug 15 21:14:43 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_height_curvature()
+  
+  Only works in 2D and on non-refined grids for the moment.
+
+Tue Aug 15 21:13:48 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Normal computation with the "column" method
+
+Tue Aug 15 21:02:12 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Volume fraction weighting of surface tension term
+
+Tue Aug 15 20:58:51 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Density is taken into account for surface tension term
+
+Mon Aug 14 13:05:09 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * New VOF advection implementation
+  
+  Works with variable interface resolution but not with solid boundaries yet.
+  Uses "Eulerian" rather than "Lagrangian" PLIC advection.
+
+Mon Aug 14 12:56:01 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * GfsVariableCurvature has moved to levelset.c
+
+Mon Aug 14 12:54:30 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Filtering of curvature along the interface
+  
+  For levelset curvature only and disabled by default.
+
+Mon Aug 14 12:15:29 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * New implementation of Youngs gradient
+  
+  Works on adaptive meshes but only in 2D for the moment.
+
+Mon Aug 14 12:11:29 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated stability criterion for surface tension
+
+Mon Aug 14 11:57:14 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Tracer advection does not save "half" values anymore
+
+Tue May 23 18:23:43 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * gfs_line_alpha() uses explicit formula
+  
+  ... rather than Newton iterations.
+
+Wed Feb 22 06:06:05 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VOF should work across refinement levels
+  
+  Also gfs_plane_volume() and gfs_plane_alpha() now do their own
+  symmetries (i.e. do not require m.x, m.y and m.z to be positive
+  anymore).
+
+Tue Feb 21 05:18:27 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Simplification of gfs_plane_volume()
+
+Mon Feb  6 02:08:32 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * CSF uses volume-fraction-weighted tension terms
+
+Sun Feb  5 14:32:49 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature must be interpolated with care on adaptive mesh
+
+Sun Feb  5 14:29:25 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Sigma and theta have nothing to do in VariableCurvature
+  
+  ...they will be back in a latter version of SourceTension.
+
+Sun Feb  5 02:43:22 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious current test case
+
+Sun Feb  5 02:38:44 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for VariableCurvature computation near boundaries
+
+Sat Feb  4 22:37:47 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableDistance computes the distance function only locally
+  
+  i.e. in a neighbourhood of the interface just large enough for
+  VariableCurvature.
+
+Sat Feb  4 22:34:43 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New functions gfs_center_gradient_stencil() and gfs_interpolate_stencil()
+
+Fri Feb  3 16:26:15 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * For curvature estimation, normals are computed using simple gradients
+  
+  ...rather than Youngs gradients. This stabilises the surface tension,
+  improves the spurious currents and it is simpler.
+
+Fri Feb  3 14:43:15 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Renamed VariableLevelSet as VariableDistance
+
+Fri Feb  3 14:15:29 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Back to semi-implicit surface tension for capillary wave test case
+  
+  Although the explicit scheme appeared to be more accurate it was just
+  by chance (i.e. the error increased when the timestep decreased).
+
+Fri Feb  3 14:13:12 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature is defined only on the interface
+  
+  It now is defined as the curvature of the piece of interface cutting
+  the cell. If the cell is not cut by the interface it is set to
+  G_MAXDOUBLE.
+
+Fri Feb  3 14:01:19 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VOF-based levelset function computation is back
+  
+  It works well with the new curvature calculation.
+
+Thu Feb  2 06:37:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  UNDO: Levelset function is computed using the VOF-reconstructed interface
+
+Thu Feb  2 23:39:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Youngs-averaging of normal divergence was unstable in some cases
+
+Thu Feb  2 23:38:10 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * The distance function value was not always correct for cells cut by the isoline
+
+Thu Feb  2 00:11:25 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Control of "implicitness" of VariableCurvature
+
+Wed Feb  1 03:34:46 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * "Semi-implicit" scheme for VariableCurvature
+
+Mon Jan 30 22:46:30 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableCurvature uses Youngs divergence
+  
+  Rather than gfs_center_gradient(). This improves the spurious currents slightly.
+
+Thu Feb  2 10:06:42 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Stability condition for surface tension was still too restrictive
+
+Thu Feb  2 06:37:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Levelset function is computed using the VOF-reconstructed interface
+
+Thu Feb  2 03:17:26 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated spurious and capwave test cases
+
+Thu Feb  2 00:16:06 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Stability constraint for surface tension was too restrictive
+
+Mon Jan 30 22:42:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * K8 smoothing kernel doesn't work
+  
+  Bubbles appear to be unstable for all smoothing lengths larger than twice the
+  grid size. For these lengths K8 does not improve over the default vertex filter.
+
+Mon Jan 30 22:40:57 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableFiltered uses K8 smoothing kernel
+
+Mon Jan 30 11:28:39 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Levelset sign was not computed properly
+
+Mon Jan 30 09:07:20 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableLevelSet computes the levelset function
+
+Sun Jan 29 01:46:09 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Stability criterion for CSF surface tension
+
+Sun Jan 29 00:36:29 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Source terms have a new generic stability() method
+
+Sun Jan 29 00:32:11 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * CSF surface tension implementation
+  
+  This is the default. The old CSS implementation (2D only) is still available as
+  SourceTensionCSS.
+
+Tue Feb 27 11:13:06 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added missing html doc titles
+
+Thu Feb 22 17:22:22 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added mime-types
+
+Tue Feb 13 16:23:32 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for mixed-cells output in gfs2oogl
+
+Wed Feb 21 13:20:19 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * darcs2dist creates 'versioned' snapshots
+
+Wed Feb 21 10:28:12 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * MacOSX does not like nested functions
+  
+  They were used to implement dx(), dy(), dz() in GfsFunction. They have been
+  replaced by using ugly (but portable) global variables.
+
+Wed Feb 21 09:52:17 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fixed labels in tutorial
+
+Wed Feb 21 09:51:54 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for darcs2dist
+
+Wed Feb 21 09:51:05 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated source doc templates
+
+Tue Feb 20 16:15:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Bigger fonts and thicker lines for lid test figures
+
+Tue Feb 20 16:14:52 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Added anchor points for some sections of the tutorial
+
+Tue Feb 20 16:14:13 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Workaround for character encoding bug in hevea 1.08
+
+Tue Feb 20 16:12:43 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * FAQ is now in the wiki not in the source doc
+
+Tue Feb 20 11:18:18 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsOutputAdaptStats works again
+
+Mon Feb 19 16:23:30 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Option for color names in tests documentation
+
+Mon Feb 19 10:25:24 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Parameter files in docs now link to "Object Hierarchy" wiki
+
+Fri Feb 16 15:55:50 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Uses hevea rather than latex2html to generate HTML docs
+
+Thu Feb 15 11:23:02 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Poisson test cases were not reliable due to race conditions in command pipes
+
+Thu Feb 15 11:20:59 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Much simplified GfsOutput command pipe implementation
+
+Wed Feb 14 17:22:58 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for variables in POSIX shells (for test suite)
+
+Wed Feb 14 14:52:27 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Fix for getopt_long and unknown arguments
+
+Wed Feb 14 14:21:35 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Updated Rayleigh-Taylor example
+
+Wed Feb 14 14:18:07 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New ppm2mpeg helper script (uses ffmpeg)
+  
+  ffmpeg is better than mjpegtools and simpler to install (debian packages are
+  readily available).
+
+Wed Jan 31 12:01:41 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Python test script works with dash
+
+Tue Jan 30 11:34:50 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * New GfsGlobal object defines "global" functions
+
+Fri Jan 19 14:22:41 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * Improved gfs_domain_remove_droplets()
+
+Thu Jan 18 10:49:19 NZDT 2007  Stephane Popinet <popinet at users.sf.net>
+  * GfsAdaptNotBox is deprecated
+
+Tue Dec 19 16:29:27 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Thin cells filled with fluid could create an incorrect topology
+
+Tue Dec 19 13:51:59 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Replaced assertion with warning in solid fractions calculation
+
+Mon Dec 11 14:52:40 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * "levelmin" is taken into account only for coarsening the mesh
+
+Wed Dec  6 16:22:46 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed Tangaroa example doc
+
+Wed Dec  6 16:21:25 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Default boundary conditions for velocity diffusion were not applied properly
+
+Tue Dec  5 11:46:04 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added Tangaroa example
+
+Thu Nov 23 14:12:03 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Aborts if the Poisson solver fails to converge
+
+Fri Nov 24 16:08:42 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed function inlining mess
+
+Fri Nov 24 10:22:12 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * glib.h is not needed if gts.h is already included
+
+Fri Nov 24 09:44:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated merging test case for new adaptive algorithm
+
+Thu Nov 23 10:40:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added "hysteresis" to adaptive algorithm
+  
+  This prevents cells being created and destroyed in quick succession.
+
+Thu Nov 23 09:36:29 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Standard error should be used rather than standard output in the examples
+
+Thu Nov 23 09:31:53 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * GfsVariableResidual wasn't scaled properly
+
+Wed Nov 22 20:25:39 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Adaptive algorithm uses a simpler technique by default
+  
+  The "global optimisation" technique is overkill when "maxcells" is not set.
+  Also, it does not allow for the simple "boolean" combination of several 
+  criteria which is possible with the simple algorithm.
+
+Sat Nov  4 19:30:25 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Improved error messages for non-closed solid surfaces
+
+Thu Nov  2 15:15:01 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Creeping Couette flow does not need advection terms
+
+Thu Nov  2 11:42:27 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * bat2gts sets higher output precision
+
+Thu Nov  2 11:41:33 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * gfs2oogl can output all variables in mixed cells
+  
+  Not just P and Vorticity.
+
+Wed Oct 25 13:45:14 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Thin cells are replaced either with fluid cells or solid cells
+  
+  They were replaced blindly by solid cells which was a very bad
+  approximation in some cases.
+
+Wed Oct 25 11:41:50 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Removed non-standard C++-style comments
+
+Sat Oct 21 16:45:54 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Gerris abort generates an error.gfs dump (for post-mortem debugging)
+
+Thu Oct 19 16:34:35 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsEventStop
+  
+  EventStop was using a temporary variable to store the previous timestep values.
+  This variable was not initialised when adapting the mesh (temporary variables 
+  are not initialised by default).
+  
+  This has been fixed by using a "real" variable instead but with a NULL name.
+  
+  This meant allowing variables with a NULL name i.e. hidden permanent variables.
+
+Wed Sep 27 03:35:10 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Inlined functions are defined once in a separate file
+
+Thu Oct 19 10:34:09 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Simplified Debian package dependencies (again)
+
+Wed Oct 18 11:23:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Simplified Debian package dependencies
+  
+  To make them compatible with Ubuntu. It's a bit messy though as I am not sure
+  what the issues are with binary compatibility of Ubuntu/Debian libraries etc...
+
+Sat Oct 14 20:18:41 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for OutputPPM for 2D GfsOcean
+
+Sun Aug 13 20:15:12 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for error handling in gfs_domain_read()
+
+Sat Aug 12 14:21:25 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Removed DX support (use GfsView instead!)
+
+Thu Oct 12 10:06:30 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references for new timestep calculation
+
+Thu Oct 12 10:05:08 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed timestep calculation for 'infinite' events
+
+Wed Oct 11 17:08:25 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed stupid timestep calculation (thanks to Chris Johnson for the bug report)
+
+Tue Oct 10 14:35:15 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Increased tolerance for capillary wave test case
+
+Mon Oct  9 10:59:49 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated test cases references
+
+Mon Oct  9 10:51:37 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Z-moments need to be computed in 2D for solid force
+
+Fri Oct  6 13:21:18 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed autogen.sh for Mac OSX
+
+Fri Oct  6 13:00:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed dependencies for Debian snapshots
+
+Tue Aug  8 11:30:06 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Set the default minimum of iterations for multilevel solvers to one
+
+Thu Aug  3 11:30:21 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed obsolete simulation file in FAQ
+
+Wed Jul 19 12:18:59 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Configure was not working properly with empty "modules" directory
+  
+  This was a problem only for systems not supporting dynamic modules.
+
+Tue Jul 18 17:31:23 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Advection update using averaged values for momentum in mixed cells was ignored
+  
+  This caused the channel test case to fail. Ultimately however this average value
+  hack should not be used at all.
+
+Fri May 12 13:29:04 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Quirk's merged fluxes are used for tracer advection rather than averaging
+  
+  They should be used also for momentum advection but this needs testing.
+
+Mon Jul  3 16:14:40 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Check for ensuring that solid fractions are positive
+  
+  Round-off errors could cause the solid fractions to be a small negative value. This could cause problems for
+  algorithms assuming (correctly) that volume fraction is always positive.
+
+Sun Jun 18 11:51:00 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Unbuffered python for test cases (to force "realtime" status)
+
+Sun Jun 11 18:31:39 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Variables have a new "description" field
+
+Sun Jun 11 16:35:55 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * DerivedVariable is now a proper object
+  
+  ... and also has a new "description" field.
+
+Sun May 28 19:12:03 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * More explicit message for systems which do not support functions
+
+Fri May 12 13:35:21 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Coarse cells on the Poisson hierarchy with only one neighbor are "turned off"
+  
+  these cells could cause poor convergence of the Poisson solver (see the dumbell
+  test case).
+
+Tue Apr 25 18:14:22 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Added "dumbbell" Poisson test case
+
+Sat Apr 22 14:08:47 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * GfsFunction understands dx(), dy() and dz()
+
+Mon Jun 12 13:02:23 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Missing script in lid test case
+
+Mon Apr  3 10:26:22 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  tagged release_0_9_2
+
+Mon Apr  3 10:25:13 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated docs
+
+Fri Mar 31 12:02:06 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete pdflatex doc stuff
+
+Thu Mar 30 17:40:12 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Cells with solid volume fraction of 0 are removed
+
+Fri Mar 24 16:40:02 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for relaxation on lowest level
+
+Fri Mar 24 12:13:50 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * Implicit Coriolis should now work with the Navier-Stokes solver
+
+Fri Mar 24 12:10:56 NZST 2006  Stephane Popinet <popinet at users.sf.net>
+  * RefineDistance uses a lower-bound for the distance...
+  
+  ... rather than the distance from the center of the cell.
+
+Wed Mar 15 17:20:29 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Thin cells are removed
+  
+  "Thin" cells are topologically complex cut cells which lead to
+  inaccurate volume-of-fluid representation of solid surfaces.  In some
+  cases the presence of these cells could lead to instabilities in the
+  projection. In all cases they would lead to inaccurate velocities.
+
+Wed Mar 15 08:43:33 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated tests for modified initial approx projection
+
+Tue Mar 14 16:17:14 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * RefineSolid defines a new derived variable "SolidCurvature"
+
+Tue Mar 14 16:15:46 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New function gfs_solid_is_thin()
+
+Tue Mar 14 16:12:21 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New interface for gfs_domain_add_derived_variable()
+
+Tue Mar 14 16:05:06 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fix for gradient computation at coarse/fine solid boundaries
+  
+  The previous version could use information from the wrong side of the
+  solid surface when constructing interpolants for cells close to a
+  solid boundary i.e. information was "leaking through" the solid
+  surface. New weighting and checks with solid surface fractions should
+  now avoid this.
+
+Tue Mar 14 16:02:42 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Merged cells can be formed using children cells at coarse/fine interfaces
+
+Fri Mar 10 17:51:08 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Time step is set before the first projection
+  
+  Previously the scaling for the tolerance on the divergence of the
+  first projection was based on a timestep of unity (i.e. usually much
+  larger than the subsequent timesteps).
+
+Fri Mar 10 10:42:39 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Debian snapshot packages were not correctly versioned
+
+Wed Mar  8 17:37:00 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Leave "specks" alone
+
+Wed Mar  8 17:33:41 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated boundaries and channel tests for weighted-centered pressure-gradient
+
+Wed Mar  8 17:32:45 NZDT 2006  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Approximate projection uses fraction-weighted average pressure gradients
+  
+  The previous unweighted averages were unstable for the "thin plate"
+  test case which has been added to the test suite.
+
+Wed Mar  8 16:45:26 NZDT 2006  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Topology was not computed correctly for solid fractions computation in 3D
+
+Sun Mar  5 20:59:59 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fix for special cases when computing solid fractions
+  
+  Solid fractions of cells cut more than once by the surface were not 
+  consistently computed by the approximate "VOF" technique. This was causing
+  convergence problems in some cases.
+  
+  These cells (rare) are now treated using a simple approximation.
+
+Wed Mar  8 16:26:27 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Removed obsolete "GtsInterface" stuff
+
+Fri Mar  3 10:26:11 NZDT 2006  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated test cases for changes in projection
+
+Fri Mar  3 12:12:59 NZDT 2006  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Examples tarball did not include animations
+
+Tue Feb 14 21:01:54 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * gfs_domain_norm_residual() was not computing a dimensionless divergence
+  
+  It now returns the error in volume conservation per timestep relative
+  to the volume of the cell.
+
+Thu Feb  9 02:53:10 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * OutputSimulation has an optional "text" format
+
+Thu Feb  9 02:52:41 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated Debian dependencies
+
+Mon Jan 30 14:47:49 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New functions gfs_vof_plane() and gfs_vof_facet()
+
+Sun Feb  5 14:21:11 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for inconsistent calls for divergence calculation
+
+Sun Feb  5 14:20:02 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * OutputTiming also reports the maximum number of variables allocated
+
+Sun Feb  5 14:15:27 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for "Pmac"
+  
+  Pmac was allocated as a temporary variable and thus was not
+  interpolated from one timestep to the next when using adaptive
+  refinement (causing trouble with the convergence rate of the Poisson
+  solver). It is now a default variable.
+
+Sun Feb  5 14:10:24 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * GfsAdapts should be treated as standard events
+  
+  ... in particular to avoid problems due to a changed order of events
+  in output files.
+
+Fri Feb  3 09:19:10 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New "nitermin" param for multilevel solvers
+  
+  This is optional but useful in some cases to prevent noise building up in a 
+  stationary solution (spurious currents test case for example).
+
+Wed Feb  1 03:33:01 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * OutputTiming computes the total running time
+  
+  i.e. does not exclude the time taken by Outputs and Events.
+
+Mon Jan 30 23:18:56 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsVariable half-events
+  
+  Half-events were never processed for GfsVariables.
+
+Mon Jan 30 22:38:17 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VariableFiltered works with odd numbers of iterations
+
+Fri Feb  3 23:50:52 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Updated macros for automake 1.8
+
+Sat Jan 28 06:43:49 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Generalised gfs_correct_normal_velocities() for CSF surface tension
+
+Sat Jan 28 14:23:57 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsVariableCurvature
+
+Sat Jan 28 10:33:58 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * MAC pressure is saved
+  
+  Both the MAC and approximate projections thus have better initial guesses. When
+  looking for stationary solutions this makes a big difference.
+
+Sat Jan 28 10:33:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Simplification of Boussinesq example
+
+Sat Jan 28 06:47:49 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Fixed typo in spurious currents test case description
+
+Sat Jan 28 06:46:55 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for GfsSourceDiffusionExplicit
+
+Sat Jan 28 11:06:45 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for generic coarse_fine() method for GfsVariable
+
+Fri Jan 27 23:08:33 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for special case of solid boundary
+  
+  When children mixed cells are all empty, a divide-by-zero would occur when
+  computing the center of "mass" of the parent cell.
+
+Fri Jan 27 23:07:10 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Better checks for construction of merged cells lists
+
+Sat Jan 21 12:29:32 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * VOF tracers are adaptively refined consistently
+
+Sat Jan 21 10:45:13 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * Generic coarse_fine() method for GfsVariable
+
+Thu Jan 19 02:55:04 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New criterion for "small" cells
+  
+  Each direction is tested independently and the presence or absence of 
+  neighbors is taken into account.
+
+Tue Jan 17 03:42:08 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * S now returns normalised surface fraction
+
+Tue Jan 17 02:27:31 NZDT 2006  Stephane Popinet <popinet at users.sf.net>
+  * New object GfsOutputScalarMaxima
+
+Wed Dec  7 13:29:57 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed typo in tutorial
+
+Tue Dec  6 10:26:46 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated test references
+  
+  GCC version 4 seems to produce slightly different results.
+
+Mon Dec  5 11:45:18 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated debian packaging and docs
+
+Fri Dec  2 18:06:32 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Debian package suggests gfsview
+
+Fri Dec  2 16:33:19 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * cvs2dist user proper versioning
+
+Fri Dec  2 16:22:30 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Debian package snapshots
+
+Wed Nov 30 22:01:47 NZDT 2005  Stephane Popinet <popinet at users.sf.net>
+  * Debian package stuff (from Marcelo's official debian archive)
+
+Tue Nov 29 10:35:08 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Workaround for bug in latex2html
+
+Tue Nov 29 16:23:49 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for use of uninitialised heap info in adaptive refinement
+
+Mon Nov 28 16:17:25 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated release instructions
+
+Mon Oct 17 12:52:21 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 0.8.0
+
+Mon Oct 17 12:49:07 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated docs for release 0.8.0
+
+Fri Oct 14 15:06:14 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputSolidForce also computes moments
+
+Fri Oct 14 11:03:59 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added missing dependencies for building docs
+
+Thu Oct 13 14:58:19 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Couette test case uses RMS-norm rather than maximum
+
+Thu Oct 13 14:56:53 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_mixed_cell_gradient uses Dirichlet conditions if set
+
+Thu Oct 13 10:18:33 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Thin-wall and waves test fixes
+
+Wed Oct 12 12:14:34 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction aborts on user declaration of reserved variable names
+
+Wed Oct 12 09:56:25 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated channel test reference
+
+Tue Oct 11 13:21:03 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Couette flow test case
+
+Tue Oct 11 12:52:48 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New functions to compute 2nd invariant of shear strain rate tensor
+
+Mon Oct 10 17:33:53 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Multilevel diffusion params are defined as part of GfsDiffusion
+
+Fri Oct  7 17:59:35 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Variable viscosity needs to be defined on all levels
+
+Fri Oct  7 11:40:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New parameter "beta" controls the implicitness of the diffusion solver
+
+Fri Oct  7 18:09:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Makefile.deps are cleaned (to force them to be updated)
+
+Thu Oct  6 11:48:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Variable viscosity coupled with variable density should now work
+
+Thu Oct  6 11:05:42 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Geometry is generated rather than stored in rt example
+
+Tue Oct  4 19:11:07 NZDT 2005  Stephane Popinet <popinet at users.sf.net>
+  * Surface tension should work with variable density
+
+Wed Oct  5 13:48:12 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Moved lid-driven cavity example to test suite
+
+Wed Oct  5 13:47:24 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added examples.tar.gz target
+
+Wed Oct  5 11:09:02 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for upwinding of MAC velocities
+  
+  The "lid-driven cavity" test case was broken by patch "Face boundary
+  conditions modified for consistent upwinding". When Dirichlet
+  conditions are imposed on the normal velocities, strict upwinding can
+  cause a violation of the solvability condition for the Poisson
+  equation. This patch fixes this problem by imposing the boundary
+  condition but only for normal MAC velocities (in effect reverting to
+  the old formulation in this case only).
+
+Tue Oct  4 17:54:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for type cast bothering gcc
+
+Tue Oct  4 18:16:14 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Restructured test/ directory
+
+Tue Oct  4 17:37:52 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete tests
+
+Tue Oct  4 16:19:31 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Simple advection test case
+
+Tue Oct  4 16:19:00 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Geostrophic adjustment test cases
+
+Tue Oct  4 11:17:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New Rayleigh-Taylor example
+
+Thu Sep 29 22:35:00 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * SourceControl does not need a timescale
+
+Thu Sep 29 15:47:56 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated capillary wave test
+
+Wed Sep 28 21:54:20 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Capillary wave test case
+
+Wed Sep 28 12:45:44 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Solid fractions are matched at coarse/fine boundaries
+
+Wed Sep 28 11:18:36 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated channel test
+
+Tue Sep 27 11:10:59 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Variable half-events for ocean models
+
+Mon Sep 26 21:15:20 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * New GfsVariableFiltered class
+
+Mon Sep 26 21:10:00 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Variable density has been fixed
+
+Mon Sep 26 14:01:45 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Some derived variables can be used in GfsFunction even with cell = NULL
+
+Mon Sep 26 12:02:07 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputHistogram can take an optional dependent variable
+
+Fri Sep 23 16:03:05 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated tests and examples for obsolete gfsview option
+
+Fri Sep 23 11:18:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * EventHarmonic can optionally compute the mean-squares error
+
+Wed Sep 21 10:29:02 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Unified implementation of 2D and 2D3 ocean models
+  
+  The 2D3 "baroclinic" model only works with a single layer for the moment.
+  The results should be exactly identical to the 2D ocean model.
+
+Tue Sep 20 20:33:27 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Pressure is centered in coastally-trapped waves test case
+
+Tue Sep 20 17:51:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New function gfs_set_2D_solid_fractions_from_surface
+
+Tue Sep 20 17:48:29 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New function gfs_cell_traverse_cut_2D
+
+Tue Sep 20 12:48:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * RefineHeight uses same interpolation routine as GfsFunction
+
+Mon Sep 19 13:23:44 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated channel test reference
+
+Mon Sep 19 12:46:05 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Weaker criteria for Poisson test cases
+
+Fri Sep 16 15:20:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete gerris_dir stuff
+
+Fri Sep 16 10:47:38 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputEnergy has been removed (it can be done better using functions)
+
+Fri Sep 16 10:06:11 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed old Poisson tests
+
+Fri Sep 16 09:21:46 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated Poisson test cases
+
+Thu Sep 15 16:47:48 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated channel and boundaries tests for "old" centered pressure gradient calculation
+
+Thu Sep 15 16:12:49 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New circular waves shallow-water test case
+
+Wed Sep 14 17:32:59 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Weighted centered pressure gradient is now an option used only by the ocean models
+
+Wed Sep 14 14:34:25 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cosmetics
+
+Wed Sep 14 13:25:43 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * EventFilter takes a time scale as extra argument
+  
+  Exponential filtering with the given timescale is used rather than
+  discrete full filtering.
+
+Wed Sep 14 11:00:26 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated references for Poisson tests
+
+Fri Sep  9 18:37:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated tests for default erelax of one
+
+Fri Sep  9 10:30:48 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Coriolis source term takes an optional linear drag parameter
+
+Wed Sep  7 17:57:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Update of 'channel' and 'boundaries' test cases for centered error estimation
+
+Wed Sep  7 17:56:08 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * 'erelax' is one by default (rather than 2)
+  
+  In most cases this is more efficient.
+
+Wed Sep  7 17:54:48 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for OutputCorrelation
+
+Tue Sep  6 18:11:01 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * @ is replaced with # before compiling functions
+  
+  Lines starting with # are treated as comments and ignored, which is a
+  problem if precompiler directives are used in the function. Using @
+  instead of # allows the use of precompiler directives.
+
+Mon Sep  5 12:32:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Channel and boundaries test cases compare non-centered variables
+
+Fri Sep  2 11:47:51 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Variables are NOT centered by default
+  
+  All variables were set to centered by default. Not sure how this
+  crept into the code but this could have potentially important follow
+  up effects. Need to check on this.
+
+Tue Aug 30 18:12:52 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cleanup of ocean divergence calculation
+
+Tue Aug 30 16:22:58 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for missing params following changes in gfs_poisson_cycle
+
+Mon Aug 29 12:39:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * CFL is applicable only if some advection scheme is used
+
+Mon Aug 29 10:12:45 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Simplified center-of-mass checks
+
+Fri Aug 26 13:32:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Small fixes for pickier gcc-4.0 warnings
+
+Fri Aug 26 13:28:13 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * "Exponential" relaxation is controlable ("erelax" parameter)
+
+Fri Aug 26 13:27:27 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed typos in FAQ
+
+Fri Aug 26 13:26:20 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Compilation of functions on MacOSX
+
+Thu Aug 18 13:10:31 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for stupid bug in gfs_init_write
+
+Wed Aug 17 18:36:30 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Extrusion of closed profiles is done correctly (no duplicate vertices)
+
+Tue Aug 16 18:52:42 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bi-directional streamlines had duplicate vertices
+
+Mon Aug 15 16:09:40 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for 2nd order streamline integration
+  
+  Streamline interval length is not constrained by cell size anymore.
+
+Mon Aug 15 16:04:26 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New functions gfs_domain_cell_traverse_condition, gfs_domain_cell_point_distance2
+  
+  And also ftt_cell_box. gfs_domain_cell_traverse_condition is used
+  as a generic replacement for gfs_domain_cell_traverse_box.
+
+Fri Aug 12 17:42:33 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated references for test cases (for the improved Poisson solver)
+
+Fri Aug 12 17:35:43 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Change to GFV files for new format
+
+Fri Aug 12 16:55:56 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Generalisation of streamline creation functions
+
+Wed Aug 10 21:40:52 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Bug fix for environment variables in gfs2tex
+
+Tue Aug  9 17:46:34 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for incorrect merging test case reference
+
+Tue Aug  9 16:37:26 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New and updated Poisson test cases
+  
+  Rather than plotting residual vs multigrid cycles, we plot residual vs
+  CPU time which is much more meaningful. A new thin plate test is
+  representative of pathological cases which did not work well with the
+  former version of the multigrid Poisson solver.
+
+Tue Aug  9 16:29:26 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Improvements to the Poisson solver
+  
+  After a full review of the Poisson solver: convergence tests with pre
+  and post relaxations, FMG implementation etc... the following
+  relatively minor changes were made: (1) the prolongation operator uses
+  "second-order" gradient-based interpolation rather than straight
+  injection, (2) the number of relaxations increases exponentially for
+  coarser levels. None of the more complex changes seemed to improve
+  convergence.
+
+Tue Aug  9 11:51:00 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New GfsClock object replaces GTimer
+  
+  Times are now given as user CPU time rather than wall-clock time.
+
+Mon Aug  8 15:37:22 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Changes to GFV files for new GfsView file format
+
+Thu Aug  4 17:11:49 NZST 2005  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * cell->data is set to NULL by gfs_cell_cleanup
+
+Thu Aug  4 17:10:44 NZST 2005  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Fix for incorrect error message in FTT I/O
+
+Thu Aug  4 17:09:35 NZST 2005  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Bug fix for stupid use of destroyed event
+
+Wed Aug  3 18:01:18 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_face_ca was failing in particular cases on 3D meshes
+
+Tue Aug  2 15:50:33 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Introduced a new GFS_FLAG_GRADIENT_BOUNDARY cell flag to fix Flather ocean bc
+  
+  The Flather ocean bc do not like the centered pressure gradient
+  interpolation used to correct the centered velocities. To revert to
+  the old "upwind" gradient interpolation a new flag has been
+  introduced. This flag is set automatically by the Flather bc.
+
+Mon Aug  1 13:52:37 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * ca.z is initialised to zero in 2D
+
+Mon Aug  1 15:04:38 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated poisson test cases with solid boundaries
+
+Thu Jul 21 16:02:28 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Changed the way gfs2tex sets environment variables
+
+Thu Jul 21 15:59:36 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added new-style Poisson test cases
+
+Wed Jul 20 22:37:10 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * New GfsPoisson solver
+
+Wed Jul 20 12:07:38 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * `shapes' has been moved to tools and is installed
+
+Mon Jul 18 15:57:47 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_function_value() can take NULL as cell argument
+
+Thu Jul 14 11:26:18 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cosmetics
+
+Thu Jul 14 10:09:12 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Face function evaluation knows about mixed cells
+  
+  This means that boundary conditions dependent on spatial coordinates
+  will correctly account for cell faces on the boundaries of the domain
+  being cut by an embdedded surface.
+
+Thu Jul 14 10:08:47 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed broken FAQ link
+
+Wed Jul 13 12:10:12 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cleaned up darcs2dist script
+
+Wed Jul 13 11:27:02 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added ChangeLog target
+
+Tue Jul 12 18:50:19 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added tarball target for tests docs
+
+Tue Jul 12 17:58:31 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Changed computation of centered pressure gradients
+  
+  This influences only the pressure gradient in mixed cells. It is now
+  computed as the surface-fraction-weighted averaged rather than just
+  the average. This is intuitively more consistent as this provides a
+  continuous interpolation when the face fractions vanish on one side of
+  the cell. More importantly this greatly stabilises the ocean model
+  near sharp headlands. It has a minimal influence on the convergence
+  rates of the test cases with boundaries (slightly improves the V
+  component and slightly degrades the U component).
+
+Tue Jul 12 16:02:03 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Version set to 0.8.0 prior to release
+
+Tue Jul 12 09:42:40 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Variable "P" is centered by default
+
+Mon Jul 11 14:58:07 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Merged Ocean1 model from 'ocean' branch
+  
+  This does not include the "fraction-weighted pressure correction" of
+  centered velocities which means that some coastlines configurations
+  will not be stable.
+
+Mon Jul 11 11:36:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for VOF plane center calculation
+  
+  Assertions were too limiting when cells were completely full or empty.
+
+Fri Jul  8 16:51:20 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Restructuring of source terms class hierarchy
+  
+  Former "vector" source terms (coriolis, surface tension, viscosity...)
+  are now derived from a common "velocity" source class which
+  automatically checks for U,V,W variables. This means that the syntax
+  in parameter files for these source terms has changed (no need to
+  specify a variable anymore).
+
+Fri Jul  8 16:42:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Spurious currents test updated for new syntax
+
+Sat Jul  9 03:18:47 NZST 2005  Sebastien Delaux <s.delaux at niwa.co.nz>
+  * Fix for locale-independent parsing of parameter files
+
+Fri Jul  8 09:31:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Minor layout changes for merging test
+
+Fri Jul  8 09:25:01 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated channel test reference
+
+Thu Jul  7 19:02:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New function gfs_function_expression()
+
+Thu Jul  7 13:01:07 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete "derived" variable stuff
+
+Thu Jul  7 12:17:27 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for floating-point bug in calculation of 2D center of mass
+  
+  Also added checks for consistency of the center of mass and center of
+  area positions.
+
+Thu Jul  7 09:28:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs2tex test() method uses gfsview-batch instead of gfsview (tests are non-interactive)
+
+Wed Jul  6 12:55:04 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated reference for spurious current test
+
+Wed Jul  6 12:54:14 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for merging conflict of speck removal stuff
+
+Wed Jul  6 12:53:25 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for deprecated casts in gfs_object_simulation()
+
+Wed Jul  6 12:51:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Upgrade of EventFilter to new memory management
+
+Tue Mar  8 17:41:29 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Specks are removed automatically from the simulation
+  
+  "Specks" are tiny (less than one cell volume) solid domains.
+
+Tue Mar  8 17:34:25 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New ocean test energy.sh, temporary modification of waves.sh
+  
+  waves.sh uses the Ocean1 2D model.
+
+Mon Feb 14 17:33:44 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New GfsEventFilter class
+  
+  Uses averages of corner values as a filter. This is very efficient to filter
+  out grid-scale oscillations of crappy schemes...
+
+Wed Jul  6 10:33:33 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated boundaries test
+
+Wed Jul  6 09:52:21 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Changed BC for boussinesq example
+
+Tue Jul  5 18:03:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New memory management changes for ocean model
+
+Tue Jul  5 14:32:46 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * EventSum takes a function rather than a variable, EventSum2 has been removed
+
+Tue Jul  5 14:32:03 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Replaced SourceViscosity with SourceDiffusion in examples for now
+
+Tue Jul  5 14:31:04 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cleanup of test script for doc/examples
+
+Tue Jul  5 10:51:33 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Spurious currents convergence is computed for finer grids
+
+Tue Jul  5 10:51:04 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * VOF scheme was not allocating temporary variable
+
+Tue Jul  5 10:30:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction identifier-finding routine was too naive
+
+Mon Jul  4 16:11:14 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated tutorial
+
+Mon Jul  4 15:23:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated reference doc
+
+Mon Jul  4 15:01:40 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for non-advected tracers with sources
+
+Thu Jun 30 21:48:14 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Allows for "tracers" only governed by source terms
+
+Thu Jun 30 21:46:27 NZST 2005  Stephane Popinet <popinet at users.sf.net>
+  * Updated reference manual
+
+Mon Jul  4 13:36:02 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * boussinesq example updated for new gfsview option
+
+Fri Jul  1 10:21:20 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for expression parsing in GfsFunction
+
+Fri Jul  1 10:20:23 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for I/O of GfsDomain
+
+Thu Jun 30 17:43:09 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Generalised parsing of GfsFunction
+
+Thu Jun 30 17:38:20 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed bug in dynamic variable allocation
+
+Wed Jun 29 17:27:34 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_function_description() can return long or short descriptions
+
+Wed Jun 29 17:26:38 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Non-repetitive outputs are always overwritten
+
+Wed Jun 29 17:22:43 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Derived variables are associated with GfsDomain
+
+Tue Jun 28 16:07:16 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsInit creates unknown variables and preserves the order of initialisation
+
+Tue Jun 28 15:43:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for incorrect parsing of GfsFunction
+
+Tue Jun 28 13:27:16 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete MPI tests
+
+Tue Jun 28 11:55:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Restructured GfsVariable implementation
+  
+  All the variables are now dynamically allocated. Temporary variables are
+  allocated when needed. There is no limit (other than memory) on the maximum
+  number of variables per cell.
+  
+  This also uncovered a serious bug: when using diffusive tracers, the solution of
+  the diffusion equation would overwrite the stored values of the pressure
+  gradients used to correct the advective terms for the velocity. With the new
+  temporary variable allocation scheme messes like that should be avoided.
+
+Mon Jun 27 18:11:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete gfs2other and unsupported gfs2vtk
+
+Thu Jun 23 09:39:21 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed Makefile for old-style surface tension test
+
+Wed Jun 22 18:55:00 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New-style spurious current test case
+
+Tue Jun 21 12:11:19 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New-style channel test, old tests have been removed
+
+Tue Jun 21 11:05:27 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputScalarHistogram correctly uses new variable definition and computes instantaneous histograms
+
+Tue Jun 21 10:14:20 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfscompare uses gfs_cell_interpolate() for error calculation of centred variables
+
+Tue Jun 21 10:13:58 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed FAQ broken link
+
+Tue Jun 21 10:12:53 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added 'boundaries' test case
+
+Tue Jul 12 15:45:54 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  tagged 0.6.4
+
+Fri Jun 17 17:53:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * merging test uses batch-mode gfsview for figure generation
+
+Fri Jun 17 12:44:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New 4-way vortex merging test case
+
+Thu Jun 16 16:00:25 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added simple periodic test case
+
+Wed Jun 15 16:54:52 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added biblio to tests doc and a few bug fixes
+
+Wed Jun 15 16:19:05 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Automated generation of summary for test docs
+
+Wed Jun 15 16:17:22 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated reference for 'reynolds/box' test case, removal of corresponding old tests
+
+Wed Jun 15 10:28:18 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added PPM animate question to FAQ
+
+Tue Jun 14 18:23:15 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Auto-documented Euler test cases replace old-style tests
+  
+  Only the equivalent test cases for reference2D/stationary1.xmgr and
+  reference2D/stationary4box1.xmgr have been implemented at this point.
+
+Mon Jun 13 22:01:28 NZST 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * New 'Reynolds' test case, replacement for 'stationary'
+  
+  Using auto-documenting with gfs2doc.
+
+Mon Jun 13 17:42:21 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * cast fix for gfs2oogl
+
+Mon Jun 13 17:41:49 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New macro ftt_vector_norm()
+
+Mon Jun 13 17:27:32 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Numbers are allowed in identifiers of macros and variables
+
+Mon Jun 13 17:26:29 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * "S" is a derived macro for solid area
+
+Mon Jun 13 17:23:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputScalarHistogram takes weight as argument
+
+Fri Jun 10 18:43:58 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputScalar takes the new GfsFunction as argument instead of a GfsVariable
+
+Fri Jun 10 17:04:31 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction now knows about "derived variables"
+  
+  This is the first step toward removing old-style derived variables
+  altogether.
+
+Thu Jun  9 17:27:00 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputScalarHistogram starts when specified and properly reopens static files
+
+Thu Jun  9 16:44:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction recognises domain variables directly
+
+Wed Jun  8 18:12:44 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Face boundary conditions modified for consistent upwinding
+  
+  The former face boundaries were not "upwind aware", this was causing
+  problems when, for example, a negative normal velocity was set as inflow
+  condition on the left of the domain and at the same time a Dirichlet BC on a
+  tracer.
+
+Tue Jun  7 10:12:24 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New object GfsOutputScalarHistogram
+
+Wed Jun  8 17:05:07 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for tracer advection (thanks to David Sterling)
+
+Tue Jun  7 10:10:59 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New macro gfs_cell_volume()
+
+Thu Jun  2 18:05:49 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New gfs_solid_normal() and gfs_pressure_force() functions
+
+Wed Jun  1 18:22:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed FAQ icons (part 2)
+
+Wed Jun  1 18:17:44 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed FAQ icons
+
+Wed Jun  1 17:54:12 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Restructuring of checks for interpolation in face_bilinear
+
+Wed Jun  1 17:52:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added FAQ and updated links and style sheets
+
+Tue May 31 11:57:21 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New SourceControl object
+
+Tue May 31 10:23:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputSimulation uses binary format by default
+
+Fri May 27 14:16:26 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Preliminary restructuring of Euler test cases
+
+Fri May 27 10:35:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cosmetics for advection tests
+
+Fri May 27 10:24:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Restructured advection order test cases
+
+Thu May 26 15:53:39 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated installation instructions
+
+Thu May 26 13:15:56 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for GfsEventScript unused handling of error output
+
+Wed May 25 17:50:41 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added boussinesq.gfv gfsview parameter file
+
+Sun Apr 24 06:29:11 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * InitVorticity takes vorticity function as argument
+  
+  Test cases have been updated and obsolete modules have been removed.
+
+Wed Apr 20 04:33:29 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for InitVorticity
+
+Thu Apr 14 04:53:16 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Update for xmgr -> xmgrace transition
+
+Thu Apr 14 04:51:11 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * VOF scheme has a CFL limit of one (not 0.5)
+
+Thu Apr 14 04:48:57 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gerris can take parameter file on standard input
+
+Sun Apr 10 01:56:34 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Minor bugfix for gfs2tex
+
+Sun Apr 10 01:55:33 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated boussinesq example
+
+Sun Apr 10 01:24:46 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Boussinesq example now uses scripting mode of GfsView
+
+Fri Apr  8 12:30:11 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated examples Makefile.am dependencies
+
+Fri Apr  8 12:29:07 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added Boussinesq example to doc
+
+Wed Apr  6 22:48:16 NZST 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * New Boussinesq example
+
+Thu Apr  7 16:08:10 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * More robust (hopefully) FPU exceptions control
+
+Thu Apr  7 16:06:51 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Decent autogen.sh script
+
+Mon Apr  4 12:03:56 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Automatic dependency of examples doc on files generated by examples
+
+Mon Apr  4 12:00:45 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Shear example updated for new C expressions in GfsFunction
+
+Mon Apr  4 11:56:21 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed problems with C expressions in GfsFunction
+  
+  Also added check for pkg-config in configure. pkg-config is required for
+  inlined functions in parameter files.
+
+Sun Apr  3 21:54:34 NZST 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * GfsInit and GfsOutputErrorNorm can use functions of variables
+
+Sun Apr  3 21:54:14 NZST 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Fixed lid example typos
+
+Sun Apr  3 21:52:43 NZST 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * New time-reversed VOF advection example
+
+Fri Apr  1 18:04:31 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New lid-driven cavity example
+
+Fri Apr  1 16:24:48 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Force flushing of OutputLocation
+
+Fri Apr  1 14:46:14 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * OutputLocation can now work with a list of several locations
+
+Fri Apr  1 11:21:36 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * EventStop can now store the difference used as criterion
+
+Wed Mar 23 16:03:56 NZST 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added missing signal header in utils.c (for BSD)
+
+Fri Mar 18 17:34:14 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * doc/examples/Makefile.deps is distributed to avoid a python dependency
+
+Tue Mar  8 17:40:36 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * bat2gts does not need to construct closed geometry anymore
+
+Tue Mar  8 13:06:58 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed obsolete CVS usermap file
+
+Thu Mar 17 18:23:45 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added automated testing of examples collection
+
+Thu Mar 17 17:30:45 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * autogen.sh must not be distributed in tarballs
+
+Thu Mar 17 15:00:02 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added simple autogen.sh script
+
+Thu Mar 17 13:33:30 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Automatic distribution of examples + improved gfs2tex code
+
+Thu Mar 17 12:18:00 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs2doc checks that the example runs
+
+Wed Mar 16 18:22:31 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs2doc script for automatically generated example documentation
+  
+  Also improved cross-links for colorised parameter files.
+
+Tue Mar 15 18:36:08 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Initial implementation of examples scripts
+
+Tue Feb 22 12:40:11 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added scripts in tools to distribution
+
+Tue Feb 22 12:16:40 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bug fix for boundary matching of solid fractions
+
+Tue Feb 22 12:13:39 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Mixed cell refinement fixes in 3D
+  
+  The advection fix could be improved (it does not currently take into account
+  the solid fractions, unlike the 2D version of the fix).
+
+Tue Nov  9 15:15:59 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Removed some of the "mixed cell refinement" constraints (gerris--ocean--0.7--patch-2)
+  gerris--ocean--0.7--patch-2
+  Keywords: 
+  
+  Probably needs more careful review.
+  
+
+Fri Feb 18 17:44:08 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction can use C statements (instead of full functions)
+  
+  but modules are not supported anymore by GfsFunction (that was never used
+  anyway).
+  
+  This patch means that things like:
+  
+    Init {} { U = sqrt(x) }
+  
+  are now legal.
+
+Fri Feb 18 17:15:45 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction can take a GTS surface as argument
+  
+  and interpolates the z-coordinate at location (x,y) to get the value of the
+  function.
+
+Fri Feb 18 12:40:30 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added ChangeLog to distribution target
+
+Fri Feb 18 12:38:26 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Removed arch obsolete garbage
+
+Tue Feb 15 12:03:56 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Spurious current test with adaptivity
+
+Tue Feb 15 12:03:04 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_object_simulation() does not work for GfsBc objects
+
+Tue Feb 15 09:45:54 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Changed interface to gfs_function_read()
+
+Fri Feb 11 19:13:08 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * New GfsAdaptFunction class
+  
+  Which uses the new GfsFunction to allow users to specify adaptive criteria
+  based on the values of local variables.
+  
+  This can be used for example to refine around an interface depending on the local
+  value of the surface tension.
+
+Fri Feb 11 15:35:30 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cosmetics
+
+Fri Feb 11 15:26:48 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * GfsFunction can now use model variables
+  
+  This can be used for example to define source terms dependent on other
+  variables.
+
+Fri Feb 11 11:58:31 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Cosmetics
+
+Thu Feb 10 14:38:54 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Capillary wave test
+
+Thu Feb 10 13:07:37 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Surface tension only works in 2D for now
+
+Wed Feb  9 12:07:03 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Renamed _gfs_source_tension_ to _T
+
+Wed Feb  9 12:05:18 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * gfs_cell_corner_interpolator now works for periodic BCs
+  
+  But only when the periodic BCs are not cut by a solid boundary.
+
+Tue Feb  8 17:05:32 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added surface tension tests to configure
+
+Tue Feb  8 16:29:09 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Minimum timestep is 1e-9
+  
+  Several functions implicitly rely on the timestep being strictly positive.
+
+Tue Feb  8 16:28:23 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Spurious currents test
+
+Tue Feb  8 13:08:20 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Replaced gfs_youngs_gradient with gfs_youngs_normal
+  
+  Which computes the three components in one operation and should be about
+  three times as fast as three calls to gfs_youngs_gradient.
+
+Tue Feb  8 12:30:22 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Proper scaling of surface tension terms
+  
+  The surface tension term also uses the volume fraction at time n+1 which
+  improves the stability significantly.
+
+Fri Feb  4 16:39:22 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Replaced "marker" surface tension implementation with tensorial-CSF formulation
+
+Sun Jan 30 20:07:21 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Implementation of Young's normal calculation for VOF
+
+Sun Jan 30 20:04:00 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Default adaptive maxlevel set to 5
+  
+  The previous default was infinite which was not too good for memory use...
+
+Sun Jan 30 20:02:45 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * VOF advection tests
+
+Sun Jan 30 16:28:09 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Timestep is computed using minimum CFL of all variables
+
+Sun Jan 30 16:27:38 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * New GfsAdvection simulation class
+
+Sun Jan 30 16:26:21 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Tracers now take advection/diffusion parameters
+
+Sun Jan 30 16:23:18 NZDT 2005  Stephane Popinet <stephane.popinet at paradise.net.nz>
+  * Graphic advection test restructured
+  
+  Uses gerris/gfsview rather than advection.c/gts2oogl/geomview etc...
+
+Fri Jan 28 00:23:13 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fix for cygwin built
+
+Wed Jan 19 18:57:30 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * darcs2dist and bat2gts are installed
+
+Wed Jan 19 18:45:44 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * darcs2dist takes URL argument
+
+Wed Jan 19 10:25:22 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Clearer error message for boundaries outside fluid domain
+
+Tue Jan 18 18:04:31 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Automatic ChangeLog generation and darcs2dist snapshot script
+
+Tue Jan 18 17:19:24 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Added GTS dependency to pkgconfig files
+
+Tue Jan 18 17:08:34 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed test/mpi
+
+Tue Jan 18 17:05:24 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed test/advection
+  
+  The results needs checking.
+
+Tue Jan 18 16:53:51 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Fixed test/poisson
+  
+  test/poisson/order still gives some inconsistent results.
+
+Tue Jan 18 16:53:18 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Updated test/poisson/convergence/reference2D
+
+Thu Dec  9 11:36:12 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Matching of surface fractions for refined mixed cells (gerris--ocean--0.7--patch-27)
+  gerris--ocean--0.7--patch-27
+  Keywords: 
+  
+  Also removal of obsolete gfs_refine_mixed() function and improvement
+  in error reporting for check_area_fractions().
+  
+
+Tue Dec  7 16:33:05 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Important bug fix for GfsEventHarmonic (gerris--ocean--0.7--patch-26)
+  gerris--ocean--0.7--patch-26
+  Keywords: 
+  
+  The right-hand-side for the least-mean-square of the offset was not
+  properly computed.
+  
+
+Tue Dec  7 11:11:25 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * isocube.h is added to distribution (gerris--ocean--0.7--patch-25)
+  gerris--ocean--0.7--patch-25
+  Keywords: 
+  
+  
+
+Tue Dec  7 11:10:26 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * gfs2oogl profile output now works without -c option (gerris--ocean--0.7--patch-24)
+  gerris--ocean--0.7--patch-24
+  Keywords: 
+  
+  
+
+Wed Dec  1 15:31:46 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Changed the way "special cases" are handled in VOF (gerris--ocean--0.7--patch-23)
+  gerris--ocean--0.7--patch-23
+  Keywords: 
+  
+  This is simpler and fixes a serious bug in the new solid fraction
+  algorithm.
+  
+
+Wed Dec  1 12:07:37 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New function gfs_domain_combine_traverse() (gerris--ocean--0.7--patch-22)
+  gerris--ocean--0.7--patch-22
+  Keywords: 
+  
+  For traversing two GfsDomain "simultaneously".
+  
+
+Mon Nov 29 12:31:51 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Made gfs_divergence() interface consistent with gfs_velocity_norm() etc... (gerris--ocean--0.7--patch-21)
+  gerris--ocean--0.7--patch-21
+  Keywords: 
+  
+  i.e. it now takes an extra GfsVariable argument.
+  
+
+Mon Nov 29 12:26:29 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Replaced static cell_is_cut function with exported gfs_cell_is_cut (gerris--ocean--0.7--patch-20)
+  gerris--ocean--0.7--patch-20
+  Keywords: 
+  
+  Used for new gfsview solid entity.
+  
+
+Thu Nov 25 12:24:12 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added isocube.h to sources (gerris--ocean--0.7--patch-19)
+  gerris--ocean--0.7--patch-19
+  Keywords: 
+  
+  
+
+Mon Nov 22 16:55:09 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Refinements interpolate existing values (gerris--ocean--0.7--patch-18)
+  gerris--ocean--0.7--patch-18
+  Keywords: 
+  
+  This allows to restart a simulation while changing the refinements of
+  some parts.
+  
+
+Wed Nov 17 17:57:12 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * In 2D3 ftt_cell_child_corner() now works for all directions (gerris--ocean--0.7--patch-17)
+  gerris--ocean--0.7--patch-17
+  Keywords: 
+  
+  
+
+Wed Nov 17 14:35:45 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New GfsEventHarmonic class (gerris--ocean--0.7--patch-16)
+  gerris--ocean--0.7--patch-16
+  Keywords: 
+  
+  Does on-the-fly harmonic analysis of a variable.
+  
+
+Tue Nov 16 17:53:23 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New utility function gfs_matrix_inverse() (gerris--ocean--0.7--patch-14)
+  gerris--ocean--0.7--patch-14
+  Keywords: 
+  
+  
+
+Tue Nov 16 13:33:03 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Option not to output solid surface in GfsOutputSimulation (gerris--ocean--0.7--patch-13)
+  gerris--ocean--0.7--patch-13
+  Keywords: 
+  
+  
+
+Tue Nov 16 10:57:45 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Weaker solid fraction consistency checks to accomodate mixed cell refinement (gerris--ocean--0.7--patch-12)
+  gerris--ocean--0.7--patch-12
+  Keywords: 
+  
+  
+
+Tue Nov 16 10:27:08 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added tolerance on timestep calculation (gerris--ocean--0.7--patch-11)
+  gerris--ocean--0.7--patch-11
+  Keywords: 
+  
+  To try to avoid very small timesteps (< 1e-9) due to round-off errors
+  on times of multiple simultaneous events.
+  
+
+Tue Nov 16 10:23:00 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Removed mixed cell refinement constraint for face traversal (gerris--ocean--0.7--patch-10)
+  gerris--ocean--0.7--patch-10
+  Keywords: 
+  
+  
+
+Tue Nov 16 09:07:48 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * bat2gts needs units specified (gerris--ocean--0.7--patch-7)
+  gerris--ocean--0.7--patch-7
+  Keywords: 
+  
+  The default length unit for GMT is inches, bat2gts works only if units
+  are cm. I have added options to the mapproject commands to override
+  the defaults.
+  
+
+Tue Nov  9 15:21:44 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * More robust GfsRefineHeight algorithm (gerris--ocean--0.7--patch-4)
+  gerris--ocean--0.7--patch-4
+  Keywords: 
+  
+  Uses the four cell corner height values rather than just the central
+  one.
+  
+
+Tue Nov  9 15:11:09 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Uses g[0] rather than res for temporary storage in adaptive algorithm (gerris--ocean--0.7--patch-1)
+  gerris--ocean--0.7--patch-1
+  Keywords: 
+  
+  We want to keep res in case its value is required for monitoring the
+  poisson solver.
+  
+
+Thu Nov  4 18:47:41 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New class GfsRefineHeight (gerris--mainline--0.7--patch-29)
+  gerris--mainline--0.7--patch-29
+  Keywords: 
+  
+  For height/depth dependent refinement in ocean model.
+  
+
+Thu Nov  4 18:36:58 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * gfs_domain_remove_ponds() now matches boundaries (gerris--mainline--0.7--patch-28)
+  gerris--mainline--0.7--patch-28
+  Keywords: 
+  
+  Only if ponds have been removed.
+  
+
+Thu Nov  4 10:27:31 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added targets libdx2D3 and gerris2D3.pc (gerris--mainline--0.7--patch-27)
+  gerris--mainline--0.7--patch-27
+  Keywords: 
+  
+  
+
+Wed Nov  3 18:10:36 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New function gfs_domain_remove_specks() (gerris--mainline--0.7--patch-26)
+  gerris--mainline--0.7--patch-26
+  Keywords: 
+  
+  "Specks" are solid islands not containing any empty cell.
+  
+  They cause stability problems for the free-surface solver of the ocean
+  model.
+  
+  They cannot be considered resolved anyway (by definition their maximum
+  thickness is smaller than one grid cell).
+  
+
+Wed Nov  3 16:06:02 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New class GfsRemovePonds (gerris--mainline--0.7--patch-25)
+  gerris--mainline--0.7--patch-25
+  Keywords: 
+  
+  Removes small "ponds" from the domain.
+  
+
+Wed Nov  3 15:02:44 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * GfsVariable are now events (gerris--mainline--0.7--patch-24)
+  gerris--mainline--0.7--patch-24
+  Keywords: 
+  
+  These events are activated at the start of the timestep loop in run()
+  methods.
+  
+  This means that the syntax for variables in parameter files has been
+  changed.
+  
+  This involved a substantial cleanup and restructuring of the events
+  and their links with simulations.
+  
+  The first application of this new mechanism is the new
+  GfsVariableResidual.
+  
+
+Wed Nov  3 12:36:57 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Split GfsVariable in new variable.{ch} file (gerris--mainline--0.7--patch-23)
+  gerris--mainline--0.7--patch-23
+  Keywords: 
+  
+  It was getting a bit too big and dispersed all over the place.
+  
+
+Tue Nov  2 16:39:40 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Fixes to solid fraction algorithm for 2D3 (gerris--mainline--0.7--patch-22)
+  gerris--mainline--0.7--patch-22
+  Keywords: 
+  
+  Because the aspect ratios of the 2D3 cells are not constant.
+  
+
+Tue Nov  2 15:07:33 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New GfsRefineSurface class (gerris--mainline--0.7--patch-21)
+  gerris--mainline--0.7--patch-21
+  Keywords: 
+  
+  The GfsRefineSolid and GfsRefineDistance classes have also been
+  reworked.
+  
+
+Tue Nov  2 13:49:45 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Fractions initialisation uses new solid fraction algorithm (gerris--mainline--0.7--patch-20)
+  gerris--mainline--0.7--patch-20
+  Keywords: 
+  
+  The gfs_cell_init_fraction() function has been replaced by
+  gfs_domain_init_fraction() which now calls
+  gfs_domain_init_solid_fractions(). 
+  
+  The GfsInitFraction event has been changed accordingly.
+  
+
+Tue Nov  2 12:32:17 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New calculation of 3D center of mass of solid fractions (gerris--mainline--0.7--patch-19)
+  gerris--mainline--0.7--patch-19
+  Keywords: 
+  
+  Uses the new 3D VOF gfs_plane_center() function.
+  
+
+Mon Nov  1 18:35:18 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Fixed bug when computing fractions of degenerate intersections (gerris--mainline--0.7--patch-18)
+  gerris--mainline--0.7--patch-18
+  Keywords: 
+  
+  We don't want to use VOF when the normal is undefined (|n| = 0),
+  rather use the face fractions directly (since the flux contribution of
+  the "normal" part is zero) to compute the fraction.
+  
+
+Mon Nov  1 12:08:09 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added VOF calculation of 3D solid fraction (gerris--mainline--0.7--patch-17)
+  gerris--mainline--0.7--patch-17
+  Keywords: 
+  
+  The center of mass calculation is not done yet.
+  
+
+Mon Nov  1 12:07:30 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Changed 2D bounding boxes for cut cells traversal (gerris--mainline--0.7--patch-16)
+  gerris--mainline--0.7--patch-16
+  Keywords: 
+  
+  Only the faces crossing the z=0 plane should be considered.
+  
+
+Mon Nov  1 12:06:48 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Removed upstream self-intersection checks (gerris--mainline--0.7--patch-15)
+  gerris--mainline--0.7--patch-15
+  Keywords: 
+  
+  This can cause the solid fractions algorithm to fail due to
+  consistency checks being violated by self-intersecting surfaces.
+  
+  The messages will be a bit obscure. We'll fix that as we go.
+  
+  The advantage is that in possibly a large number of cases with "minor"
+  self-intersections (e.g. nearly collocated vertices etc...) the
+  algorithm will proceed and should produce valid solid fractions.
+  
+
+Mon Nov  1 12:06:09 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Domain traversal for painting algorithm (gerris--mainline--0.7--patch-14)
+  gerris--mainline--0.7--patch-14
+  Keywords: 
+  
+  The previous "box" traversal did not work for the painting algorithm
+  (which does not know box boundaries).
+  
+  Traversing the whole domain rather than each box fixes the problem.
+  
+  Also, the painting algorithm used to also traverse boundary cells. A
+  check has been added to avoid that.
+  
+
+Mon Nov  1 12:05:05 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * preliminary version of new 3D solid fraction computation (gerris--mainline--0.7--patch-13)
+  gerris--mainline--0.7--patch-13
+  Keywords: 
+  
+  Only computes the face fractions at this point (the painting algorithm
+  works fine unchanged from 2D).
+  
+
+Mon Nov  1 12:03:11 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Changed "temporary" to "permanent" for GfsVariable (gerris--mainline--0.7--patch-12)
+  gerris--mainline--0.7--patch-12
+  Keywords: temporary
+  
+  permanent is a pointer to the permanent variable stored in this
+  temporary variable.
+  
+
+Thu Oct 28 18:42:27 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New algorithm for 2D solid fractions computation (gerris--mainline--0.7--patch-11)
+  gerris--mainline--0.7--patch-11
+  Keywords: 
+  
+  Does not use the gts_surface_inter etc... functions but a simple
+  computation of the intersections of the sides of the cell with the
+  surface, combined with a linear approximation of the piece of the
+  surface contained in the cell.
+  
+  This is *much* faster, simpler and should be robust. It is also much
+  less picky about the degeneracies of the surfaces it can deal with.
+  
+  It does not work yet for a varying level of refinement along the
+  surface.
+  
+
+Thu Oct 28 12:43:56 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Check for diffusion terms before warning (gerris--mainline--0.7--patch-10)
+  gerris--mainline--0.7--patch-10
+  Keywords: 
+  
+  The "soid surface cuts boundary cells" warning is only relevant if
+  diffusion terms are present.
+  
+
+Thu Oct 28 12:34:13 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Improved solid fractions computation (gerris--mainline--0.7--patch-9)
+  gerris--mainline--0.7--patch-9
+  Keywords: 
+  
+  Both solid fractions computation and GfsRefineSolid use the new
+  gfs_cell_traverse_cut function. This has several advantages: no need
+  for pre-computation of a bounding-box tree, faster (O(log(N))).
+  
+  GfsRefineSolid is *much* faster (at least one order of magnitude).
+  
+  A paiting algorithm is used to set fractions for cells which are not
+  cut by the solid boundary. This is simpler than the ray-casting
+  technique (no need for bounding-box tree).
+  
+
+Thu Oct 28 12:01:04 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added timers for initial refinement and solid fractions (gerris--mainline--0.7--patch-8)
+  gerris--mainline--0.7--patch-8
+  Keywords: 
+  
+  
+
+Wed Oct 27 15:09:37 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * New function gfs_cell_traverse_cut (gerris--mainline--0.7--patch-7)
+  gerris--mainline--0.7--patch-7
+  Keywords: 
+  
+  Fast traversal of cells cut by a surface. The cost of traversal scales
+  roughly like log(N) where N is the total number of cells traversed.
+  
+
+Wed Oct 27 12:22:55 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Added bat2gts script (gerris--mainline--0.7--patch-6)
+  gerris--mainline--0.7--patch-6
+  Keywords: 
+  
+  For generating ocean bathymetry files.
+  
+
+Tue Jan 18 15:28:17 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Bumped micro version
+
+Thu Oct 21 15:51:33 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Automatically adds PS and Div variables to ocean model (gerris--mainline--0.7--patch-5)
+  gerris--mainline--0.7--patch-5
+  Keywords: 
+  
+  Using a overloading of the read() method of GfsOcean.
+  
+
+Wed Oct 20 17:56:25 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Replaced GfsOutputStreakline with GfsOutputParticle (gerris--mainline--0.7--patch-4)
+  gerris--mainline--0.7--patch-4
+  Keywords: 
+  
+  GfsOutputStreakline was weird. GfsOutputParticle is a lagrangian
+  tracer integrator.
+  
+
+Wed Oct 20 17:08:17 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Fixed cloning of GfsVariable. (gerris--mainline--0.7--patch-3)
+  gerris--mainline--0.7--patch-3
+  Keywords: 
+  
+  The (non)-cloning of the surface_bc field of GfsVariable was crashing
+  the code when destroying cloned variables. This has been solved by not
+  cloning surface_bc and source terms.
+  
+
+Wed Oct 20 12:19:10 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Fixed DX modules (gerris--mainline--0.7--patch-2)
+  gerris--mainline--0.7--patch-2
+  Keywords: 
+  
+  
+
+Tue Oct 19 15:10:19 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Updates for release 0.6.0 (gerris--mainline--0.5--patch-8)
+  gerris--mainline--0.5--patch-8
+  Keywords: 0.6.0
+  
+  Tutorial and reference manual have been updated.
+  A fix for MacOSX libtool has been included.
+  Fix for incorrect call to gfs_interpolate in gfs2oogl.
+  Fix for branch "stable" in cvs2cl.pl
+  
+
+Mon Oct 18 15:36:26 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * GTS solid files can also be written in binary format. (gerris--mainline--0.5--patch-7)
+  gerris--mainline--0.5--patch-7
+  Keywords: 
+  
+  
+
+Thu Oct 14 16:31:51 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * gfs_interpolate uses proper bi(tri)linear interpolation (gerris--mainline--0.5--patch-6)
+  gerris--mainline--0.5--patch-6
+  Keywords: 
+  
+  Corner values for the cell are computed using gfs_cell_corner_value
+  and then used to do the bi(tri)linear interpolation. This has been
+  tested succinctly and provides true continuous (C1)
+  interpolation. This was not the case before.
+  
+  An important note is that the value at the center of the cell obtained
+  by (bi)trilinear interpolation is NOT equal to the variable value at
+  the center (it is equal to the mean of the corner values).
+  
+
+Thu Oct 14 11:12:50 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Support for binary simulation files (gerris--mainline--0.5--patch-5)
+  gerris--mainline--0.5--patch-5
+  Keywords: 
+  
+  Binary files speed up reading time by a factor of ~5 for big simulations.
+  There is no consideration of endianess at this point.
+  
+
+Wed Oct 13 09:01:45 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Checks for periodic bc in interpolations (gerris--mainline--0.5--patch-4)
+  gerris--mainline--0.5--patch-4
+  Keywords: 
+  
+  Periodic boundary conditions do not work yet with interpolations for
+  solid boundary fluxes and for corner values.
+  
+
+Mon Oct 11 14:39:00 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Control of diffusion bc on immersed boundaries (gerris--mainline--0.5--patch-3)
+  gerris--mainline--0.5--patch-3
+  Keywords: 
+  
+  Boundary conditions on immersed boundaries for the diffusion equation
+  can now be set in parameter files.
+  
+
+Fri Oct  8 17:35:00 NZDT 2004  Stephane Popinet <popinet at users.sourceforge.net>
+  * Conversion of .cvsignore to .arch-inventory (gerris--mainline--0.5--patch-1)
+  gerris--mainline--0.5--patch-1
+  Keywords: 
+  
+  
+
+Tue Jan 18 13:32:33 NZDT 2005  Stephane Popinet <s.popinet at niwa.co.nz>
+  * Initial commit (s.popinet at niwa.co.nz--2004/gerris--mainline--0.5)
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..54caf7c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..f407070
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,46 @@
+## Process this file with automake to produce Makefile.in
+
+ACLOCAL_AMFLAGS = -I m4
+
+# changed this to your dput command
+DPUT = socksify dput
+
+# change this to your launchpad PPA
+# configured in ~/.dput.cf
+PPA = gerris-ppa
+
+# change this to the ID of the PPA GPG key
+KEY = 07AB22DC
+
+# change this to the html changelog for this launchpad release
+LOG = /var/www/gerris/version/gerris_changes
+
+SUBDIRS = modules src tools test doc desktop
+
+EXTRA_DIST = ChangeLog m4
+
+if DARCS_CONTROLLED
+DARCS_CHANGELOG = changelog
+else
+DARCS_CHANGELOG = 
+endif
+
+ChangeLog: $(DARCS_CHANGELOG)
+
+changelog:
+	darcs changes | grep -v Ignore-this: > ChangeLog
+
+debian-snapshot: $(DARCS_CHANGELOG) config.h src/version.h
+	sh debian/changelog.sh
+	dpkg-buildpackage -rfakeroot -b
+	rm -f debian/repo/*
+	mv -f ../*.changes ../*.deb debian/repo
+	cd debian/repo && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
+
+launchpad-snapshot: $(DARCS_CHANGELOG) config.h src/version.h dist
+	tar xzf gerris-?.?.?.tar.gz
+	cd gerris-?.?.? && ./configure && sh debian/changelog.sh $(LOG) && dpkg-buildpackage -rfakeroot -k$(KEY) -S -sa
+	rm -f gerris-?.?.?.tar.gz
+	rm -r -f gerris-?.?.?
+	$(DPUT) $(PPA) gerris-snapshot_*_source.changes
+	rm -f gerris-snapshot_*
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..af0cfd9
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,786 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+	THANKS TODO compile config.guess config.sub depcomp install-sh \
+	ltmain.sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+ACLOCAL_AMFLAGS = -I m4
+
+# changed this to your dput command
+DPUT = socksify dput
+
+# change this to your launchpad PPA
+# configured in ~/.dput.cf
+PPA = gerris-ppa
+
+# change this to the ID of the PPA GPG key
+KEY = 07AB22DC
+
+# change this to the html changelog for this launchpad release
+LOG = /var/www/gerris/version/gerris_changes
+SUBDIRS = modules src tools test doc desktop
+EXTRA_DIST = ChangeLog m4
+ at DARCS_CONTROLLED_FALSE@DARCS_CHANGELOG = 
+ at DARCS_CONTROLLED_TRUE@DARCS_CHANGELOG = changelog
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+	ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-generic \
+	clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+	dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+ChangeLog: $(DARCS_CHANGELOG)
+
+changelog:
+	darcs changes | grep -v Ignore-this: > ChangeLog
+
+debian-snapshot: $(DARCS_CHANGELOG) config.h src/version.h
+	sh debian/changelog.sh
+	dpkg-buildpackage -rfakeroot -b
+	rm -f debian/repo/*
+	mv -f ../*.changes ../*.deb debian/repo
+	cd debian/repo && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
+
+launchpad-snapshot: $(DARCS_CHANGELOG) config.h src/version.h dist
+	tar xzf gerris-?.?.?.tar.gz
+	cd gerris-?.?.? && ./configure && sh debian/changelog.sh $(LOG) && dpkg-buildpackage -rfakeroot -k$(KEY) -S -sa
+	rm -f gerris-?.?.?.tar.gz
+	rm -r -f gerris-?.?.?
+	$(DPUT) $(PPA) gerris-snapshot_*_source.changes
+	rm -f gerris-snapshot_*
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..a99e3fd
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,284 @@
+03/04/2006: Release 0.9.2
+
+The most significant improvements in this release are:
+
+- Important bug fixes and improvements for the multilevel Poisson
+  solver can reduce the overall computational cost by a factor of five
+  or more depending on the problem.
+- Variable mesh resolution along solid boundaries is now allowed and
+  has been well tested (note however that time-adaptive variable
+  resolution is not allowed on solid boundaries yet).
+- The robustness of the solution procedure has been much improved in
+  the case of very complex solid boundaries.
+
+Other improvements include:
+
+- Debian package snapshots.
+- Adaptive refinement of VOF-advected tracers.
+- Preliminary implementation of CSF surface tension using Renardy et
+  al. "proper discretisation".
+- Solid boundaries can be refined according to the local curvature.
+- Implicit Coriolis terms work with the Navier-Stokes solver.
+- Support for "thin" 3D domains.
+
+Bug fixes:
+
+- Several bug fixes for special cases of solid boundaries.
+- Bug fixes for "GfsAdapt" events.
+
+17/10/2005: Release 0.8.0
+
+Quite a lot of important new features and bug fixes in this release. I
+will just give a summary below, the ChangeLog has all the details.
+
+- Variable density Navier-Stokes is back (but still needs more
+testing). Have a look at the new Rayleigh-Taylor example.
+
+- Solid fractions of embedded boundaries are computed using a new
+algorithm. This algorithm does not attempt to compute exact volume
+fractions (as was done before using the boolean operations of GTS) but
+is at least second-order accurate (which is enough). Consequently it
+is much faster (approx. 20 times) and also much more robust. It can
+tolerate some degeneracy in surfaces, as well as non-closed surfaces
+(with cracks etc...).
+
+- Embedded boundaries can now have a variable resolution, but this
+needs more testing. They cannot be adaptively refined yet, however.
+
+- The linearised shallow-water 2D ocean model has been tested for
+prediction of tides around New Zealand (see the paper by Rym Msadek
+in the bibliography section).
+
+- Volume-of-fluid Continuum-Surface-Stresses (CSS) formulation and
+associated tests (spurious currents, capillary waves...). Only 2D for now.
+
+- GfsFunction can use model variables (have a look at the Boussinesq
+example). Complex source terms can be defined directly in the
+parameter file.
+
+- The dynamic allocation of variables has been restructured. There is
+no "pre-allocated" or static variables anymore. Everything is
+dynamic. Temporary variables are also dynamically allocated and
+freed. This eliminates implicit dependencies between different
+routines relying on the same temporary variables. Not surprisingly,
+several bugs were uncovered when this was implemented (i.e. "routines
+stepping on each others toes").
+
+- After a full review, the Poisson solver has been improved
+slightly. Some pathological now converge (see the thin-wall test
+case).
+
+- Support for variable viscosity in the diffusion solver can be used
+to solve for non-Newtonian fluids (including LES turbulence viscosity
+models). This works even for very stiff material laws (e.g. Bingham
+fluids).
+
+- The diffusion solver can be tuned from semi-implicit to fully
+implicit. This is useful for Stokes flows and/or non-Newtonian fluids.
+
+- Switched to darcs for version control (after a short period of
+trying to use arch). Darcs is very nice.
+
+- An automated test suite is ran automatically every night (if the
+code changes).
+
+- Examples and associated Latex and HTML documentation can be
+generated easily. Several examples are included on the web
+site. Contributed examples from users should be easy (see the last
+section of the examples page for details).
+
+- A FAQ has been added. Feel free to send corrections and additions.
+
+- Snapshots are generated only if the test suite passes.
+
+Minor changes and improvements:
+
+- OutputSimulation uses binary format by default.
+
+- GfsFunction can use C statements (instead of full functions).
+
+- New objects to compute online histograms (OutputScalarHistogram) and
+perform harmonic analysis (EventHarmonic).
+
+- Several MacOSX specific fixes.
+
+20/10/2004: Release 0.6.0
+
+First the good news:
+
+Diffusion equations with complex boundary conditions can now be solved
+in 3D!
+
+Now the bad news:
+
+Variable density support is broken in this version (use 0.3.0 if you
+need it). The reason is that this part of the code needs to be
+reviewed/generalised to make sure it does the right thing.
+
+The main changes/improvements in this version are:
+
+- Support for diffusion equations in 3D complex geometries
+- Flexible boundary conditions on embedded solid surfaces for
+  diffusion equation in parameter files (see the tutorial)
+- Updated tutorial and reference manual
+- An initial implementation of a shallow-water 2D and 3D hydrostatic
+  ocean model with semi-implicit Coriolis source terms and barotropic
+  equation (multigrid for Helmoltz equation)
+- Support for different types of simulations (ocean and incompressible
+  Euler/NS for the moment)
+- Support for multiple tracers
+- Much improved interpolation of variables
+- New consistent pressure correction formulation (which works with
+  momentum source terms near boundaries)
+- MPI configuration reworked (uses mpicc): tested with mpich and
+  lam-mpi
+- Bounding boxes for PPM output: allows to select a limited area for
+  PPM output
+- Optional binary file format (4 to 5 times faster file read)
+
+Minor bug corrections and improvements:
+
+- pkgconfig support
+- MacOSX support
+- Bug fix for 64 bits machines
+- Relaxed constraints on refinement (still needs work)
+- External library links in GfsFunction
+- Short keyword support
+- Lambda2 criterion of Jeong and Hussain (for vortex detection)
+- etc...
+
+20/05/2004: Release 0.3.0
+
+Quite a lot has happened since 0.2.0. The main changes/improvements are:
+
+- On systems supporting dynamic linking, functions of space and time
+can be used instead of constants for most objects which require a
+numerical argument. This is particularly useful for initialisation
+(each field can be set using functions of space and time) where almost
+any mathematical description of the initial conditions can be written
+directly in the parameter file (no need to create a custom module
+etc...). The same mechanism can also be used to define the initial
+refinement of the grid (i.e. specify the mesh density as a
+mathematical function directly in the parameter file) or variable
+source terms.
+
+- The boundary condition subsystem has been entirely revamped. It is
+now possible to define complex boundary conditions by combining
+independent boundary conditions (Dirichlet, Neumann etc...) for each
+variable. Dynamic functions can be used within this framework which
+allows for variable in space (e.g. profiles) and in time boundary
+conditions.
+
+- The code now includes a multigrid semi-implicit diffusion solver. It
+can work together with embedded solid boundaries in 2D but not yet in
+3D. It is possible to accurately specify the boundary conditions
+(Dirichlet or Neumann) for the diffused variable on the solid
+boundaries. All this allows for the solution of advection-diffusion
+equations such as incompressible Navier-Stokes. Due to the stability
+of the semi-implicit scheme it is also possible to solve pure Stokes
+flows with no restriction on the time step.
+
+- The adaptive engine has been rewritten. It is now possible to
+control the maximum size of the simulation. When this maximum size is
+reached, the algorithm will optimally distribute this maximum number
+of cells so that the adaptive criterion is minimized.
+
+- Note that the parameter file arguments of several objects have
+changed (GfsAdapt in particular), so that full parameter file
+compatibility with 0.2.0 is not guaranteed.
+
+- Volume of Fluid or standard Godunov advection schemes can now be
+selected in parameter files.
+
+- New object outputs the pressure and viscous forces exerted on the
+embedded solid boundary.
+
+- The pressure is now properly scaled.
+
+- Plus a large number of bug fixes, small improvements etc...
+
+Have a look at the ChangeLog for details.
+
+08/01/2003: Release 0.2.0
+
+This new release of Gerris includes a number of new features as well
+as some major code restructuring. 
+
+The GTS library version 0.7.1 is required. It includes major
+improvements for boolean operations between surfaces which greatly
+improve the robustness of the treatment of solid boundaries within
+Gerris.
+
+The major changes are listed below. For a detailed summary see the
+ChangeLog.
+
+New features:
+
+- Support for the variable density incompressible Euler equations.
+
+- Support for user-defined source terms for any variable. Gaussian
+  tracer source terms and constant source terms (e.g. acceleration of
+  gravity in momentum equation) are provided.
+
+- Base domain does not have to be cubic anymore. Independent length
+  scales can be provided for each dimension.
+
+- Module for OpenDX allowing direct import of Gerris simulation files.
+
+- Updated documentation and tutorial: section about user-defined
+  extension modules for initial conditions.
+
+- Support for dynamic allocation of additional cell variables
+  i.e. extension modules can dynamically add additional variables if
+  needed.
+
+- Automatic compilation and installation of 2D and 3D versions. 
+
+- Preliminary implementation of a second-order Volume Of Fluid (VOF)
+  advection scheme.
+
+- A new GfsAdaptNotBox class can be used to specify parts of the
+  domain which do not need to be refined. This is particularly useful
+  for implementing absorbing outflow conditions.
+
+Improvements and restructuring:
+
+- Improved adaptive refinement algorithm.
+
+- Restructuring of the test suite.
+
+19/06/2002: Release 0.1.0
+
+Hi all,
+
+I am glad to announce the first "official" release of Gerris.
+
+It needs the latest version of GTS (0.6.0) to compile.
+
+A major change since last month is the addition of "dynamic adaptive
+mesh refinement" i.e. the distribution of cells changes according to
+what is happening to the solution. Have a look at the gallery on the
+web site for a graphical illustration.
+
+here:
+
+http://gfs.sourceforge.net/gallery.html
+
+and here (at the bottom of the page):
+
+http://gfs.sourceforge.net/tangaroa.html
+
+I also wrote a short tutorial which should help you get started with
+the code (available online and in the distribution in doc/tutorial).
+
+http://gfs.sourceforge.net/tutorial/tutorial1.html
+
+Any feedback is of course welcome,
+
+Enjoy,
+
+Stephane
+
+11/12/2001: Inital CVS checkin
+01/08/2001: Initial setup
+ LocalWords:  GfsAdaptNotBox
diff --git a/README b/README
new file mode 100644
index 0000000..3267895
--- /dev/null
+++ b/README
@@ -0,0 +1,27 @@
+General Information
+===================
+
+Gerris also known as the GNU Flow Solver (GFS) aims to be a generic
+tool for the numerical simulation of fluid flows.
+
+The official web site is: http://gfs.sourceforge.net
+
+Copying
+=======
+
+Gerris is distributed under the terms of the General Public License which
+is compliant with the guidelines of the Open Source and Free Software
+Fundations. See the file COPYING for details.
+
+Installation
+============
+
+Unix users (including Windows users under Cygwin):
+
+./configure
+make
+make install
+
+See the file 'INSTALL' for generic configure instructions and the tutorial
+in doc/tutorial for an introduction on how Gerris works.
+
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..f3f69bb
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,15 @@
+Gerris would not have been as good :) without the contributions of the
+following people (in random order):
+
+Dan Kelley
+R Sai Kiran
+David Sterling
+Frank Griessbaum
+Ben Moat
+Vladimir Kolobov
+Philip Rubini
+Geordie McBain
+Ruhollah Tavakoli
+Wolfgang Betz
+Gaurav Tomar
+Daniel Fuster
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..56cfe58
--- /dev/null
+++ b/TODO
@@ -0,0 +1,45 @@
+- Add corner flow test case.
+
+- The boundary conditions for the gradient of the pressure could be
+improved.
+
+Possible speed optimizations: 
+
+- packing of parallel communications (in the case of domain composed
+of several boxes).  
+
+- parallel match() uses doubles for cell layout description, guint
+would be more space efficient.
+
+- multiple calls to fl_domain_depth() are not needed => store maxlevel
+in FlDomain struct and update it only when necessary (i.e. when
+refining/coarsening etc...).
+
+Dodgy stuff:
+
+- Check that gfs_face_gradient() is used properly when not used for
+  poisson problem (i.e. advection) (particularly in 3D with the factor of 2).
+
+Future stuff:
+
+- Richardson extrapolation => being able to compute advection terms
+  one level above the leaf cells.
+
+- Adaptation given a constraint on maximum domain size (i.e. optimal
+  distribution of a finite number of cells) (done 09/2003)
+
+- Generalize relaxation: (done 11/2002)
+  * necessary for Crank-Nicholson
+  *    "      for variable density (done 11/2002)
+
+- GFS -> OpenDX file conversion (done 11/2002, DX module).
+
+- Optimize parallel code by overlapping communications and computations: 
+  This could be done relatively easily (in Poisson relaxation for
+  example) by first relaxing the cells close to the boundaries, start
+  the communications, relax the remaining bulk cells then synchronize
+  the communications.
+
+== for 2D3 ==
+
+check on "FTT_CELLS/2" and "ftt_cell_children_direction"
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..60beb3d
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,402 @@
+# Configure paths for GTS
+# Stéphane Popinet  2001-10-4
+#       adapted from
+# Configure paths for GLIB
+# Owen Taylor       97-11-3
+
+dnl AM_PATH_GTS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for GTS, and define GTS_CFLAGS and GTS_LIBS
+dnl
+AC_DEFUN([AM_PATH_GTS],
+[dnl 
+dnl Get the cflags and libraries from the gts-config script
+dnl
+AC_ARG_WITH(gts-prefix,[  --with-gts-prefix=PFX   Prefix where GTS is installed (optional)],
+            gts_config_prefix="$withval", gts_config_prefix="")
+AC_ARG_WITH(gts-exec-prefix,[  --with-gts-exec-prefix=PFX Exec prefix where GTS is installed (optional)],
+            gts_config_exec_prefix="$withval", gts_config_exec_prefix="")
+AC_ARG_ENABLE(gtstest, [  --disable-gtstest       Do not try to compile and run a test GTS program],
+		    , enable_gtstest=yes)
+
+  if test x$gts_config_exec_prefix != x ; then
+     gts_config_args="$gts_config_args --exec-prefix=$gts_config_exec_prefix"
+     if test x${GTS_CONFIG+set} != xset ; then
+        GTS_CONFIG=$gts_config_exec_prefix/bin/gts-config
+     fi
+  fi
+  if test x$gts_config_prefix != x ; then
+     gts_config_args="$gts_config_args --prefix=$gts_config_prefix"
+     if test x${GTS_CONFIG+set} != xset ; then
+        GTS_CONFIG=$gts_config_prefix/bin/gts-config
+     fi
+  fi
+
+  for module in . $4
+  do
+      case "$module" in
+         gmodule) 
+             gts_config_args="$gts_config_args gmodule"
+         ;;
+         gthread) 
+             gts_config_args="$gts_config_args gthread"
+         ;;
+      esac
+  done
+
+  AC_PATH_PROG(GTS_CONFIG, gts-config, no)
+  min_gts_version=ifelse([$1], ,0.4.2,$1)
+  AC_MSG_CHECKING(for GTS - version >= $min_gts_version)
+  no_gts=""
+  if test "$GTS_CONFIG" = "no" ; then
+    no_gts=yes
+  else
+    GTS_CFLAGS=`$GTS_CONFIG $gts_config_args --cflags`
+    GTS_LIBS=`$GTS_CONFIG $gts_config_args --libs`
+    gts_config_major_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    gts_config_minor_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    gts_config_micro_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_gtstest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GTS_CFLAGS"
+      LIBS="$GTS_LIBS $LIBS"
+dnl
+dnl Now check if the installed GTS is sufficiently new. (Also sanity
+dnl checks the results of gts-config to some extent
+dnl
+      rm -f conf.gtstest
+      AC_TRY_RUN([
+#include <gts.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  system ("touch conf.gtstest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = g_strdup("$min_gts_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_gts_version");
+     exit(1);
+   }
+
+  if ((gts_major_version != $gts_config_major_version) ||
+      (gts_minor_version != $gts_config_minor_version) ||
+      (gts_micro_version != $gts_config_micro_version))
+    {
+      printf("\n*** 'gts-config --version' returned %d.%d.%d, but GTS (%d.%d.%d)\n", 
+             $gts_config_major_version, $gts_config_minor_version, $gts_config_micro_version,
+             gts_major_version, gts_minor_version, gts_micro_version);
+      printf ("*** was found! If gts-config was correct, then it is best\n");
+      printf ("*** to remove the old version of GTS. You may also be able to fix the error\n");
+      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+      printf("*** required on your system.\n");
+      printf("*** If gts-config was wrong, set the environment variable GTS_CONFIG\n");
+      printf("*** to point to the correct copy of gts-config, and remove the file config.cache\n");
+      printf("*** before re-running configure\n");
+    } 
+  else if ((gts_major_version != GTS_MAJOR_VERSION) ||
+	   (gts_minor_version != GTS_MINOR_VERSION) ||
+           (gts_micro_version != GTS_MICRO_VERSION))
+    {
+      printf("*** GTS header files (version %d.%d.%d) do not match\n",
+	     GTS_MAJOR_VERSION, GTS_MINOR_VERSION, GTS_MICRO_VERSION);
+      printf("*** library (version %d.%d.%d)\n",
+	     gts_major_version, gts_minor_version, gts_micro_version);
+    }
+  else
+    {
+      if ((gts_major_version > major) ||
+        ((gts_major_version == major) && (gts_minor_version > minor)) ||
+        ((gts_major_version == major) && (gts_minor_version == minor) && (gts_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of GTS (%d.%d.%d) was found.\n",
+               gts_major_version, gts_minor_version, gts_micro_version);
+        printf("*** You need a version of GTS newer than %d.%d.%d. The latest version of\n",
+	       major, minor, micro);
+        printf("*** GTS is always available from http://gts.sourceforge.net.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the gts-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of GTS, but you can also set the GTS_CONFIG environment to point to the\n");
+        printf("*** correct copy of gts-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+      }
+    }
+  return 1;
+}
+],, no_gts=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_gts" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$GTS_CONFIG" = "no" ; then
+       echo "*** The gts-config script installed by GTS could not be found"
+       echo "*** If GTS was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GTS_CONFIG environment variable to the"
+       echo "*** full path to gts-config."
+     else
+       if test -f conf.gtstest ; then
+        :
+       else
+          echo "*** Could not run GTS test program, checking why..."
+          CFLAGS="$CFLAGS $GTS_CFLAGS"
+          LIBS="$LIBS $GTS_LIBS"
+          AC_TRY_LINK([
+#include <gts.h>
+#include <stdio.h>
+],      [ return ((gts_major_version) || (gts_minor_version) || (gts_micro_version)); ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GTS or finding the wrong"
+          echo "*** version of GTS. If it is not finding GTS, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+	  echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+          echo "***"],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GTS was incorrectly installed"
+          echo "*** or that you have moved GTS since it was installed. In the latter case, you"
+          echo "*** may want to edit the gts-config script: $GTS_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     GTS_CFLAGS=""
+     GTS_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GTS_CFLAGS)
+  AC_SUBST(GTS_LIBS)
+  rm -f conf.gtstest
+])
+
+dnl  DX_INSTALL_PATH
+dnl  Tries to find the location where dx is installed if it
+dnl  can not then it defaults to /usr/local/dx
+dnl  --------------------------------------------------------
+AC_DEFUN([DX_INSTALL_PATH],
+[
+AC_CACHE_CHECK([for dx install path], ac_cv_dx_install_path,
+[
+AC_MSG_RESULT(locating)
+DX_DEFAULT_INST=/usr/local/dx
+AC_CHECK_PROGS( DX, dx )
+
+DX_PATH=""
+if test -n "$DX" ; then
+  AC_MSG_CHECKING([for path via "dx -whereami"])
+  DX_PATH=`$DX -whereami | grep "installed in" | sed -e "s/installed in //" -e "s'^\(.*\)\/$'\1'"`
+  if test -z "$DX_PATH" ; then
+        AC_MSG_RESULT([warning: old version of dx script in path])
+  elif test "x$ARCH" = "xintelnt" ; then
+	DX_PATH=`cygpath -w -s "$DX_PATH"`
+  fi
+fi
+
+if test -z "$DX_PATH" ; then
+  AC_MSG_CHECKING([for /usr/local/bin/dx])
+  if test -x "/usr/local/bin/dx" ; then
+     DX_PATH=`/usr/local/bin/dx -whereami | grep "installed in" | sed -e "s/installed in //"`
+  fi
+
+  if test -z "$DX_PATH" ; then
+        AC_MSG_WARN([Missing dx script--please install OpenDX first.])
+  elif test "x$ARCH" = "xintelnt" ; then
+	DX_PATH=`cygpath -w -s "$DX_PATH"`
+  fi
+fi
+ac_cv_dx_install_path=$DX_PATH
+])
+DX_PATH=$ac_cv_dx_install_path
+])
+# Configure path for the GNU Scientific Library
+# Christopher R. Gabriel <cgabriel at linux.it>, April 2000
+
+
+AC_DEFUN([AM_PATH_GSL],
+[
+AC_ARG_WITH(gsl-prefix,[  --with-gsl-prefix=PFX   Prefix where GSL is installed (optional)],
+            gsl_prefix="$withval", gsl_prefix="")
+AC_ARG_WITH(gsl-exec-prefix,[  --with-gsl-exec-prefix=PFX Exec prefix where GSL is installed (optional)],
+            gsl_exec_prefix="$withval", gsl_exec_prefix="")
+AC_ARG_ENABLE(gsltest, [  --disable-gsltest       Do not try to compile and run a test GSL program],
+		    , enable_gsltest=yes)
+
+  if test "x${GSL_CONFIG+set}" != xset ; then
+     if test "x$gsl_prefix" != x ; then
+         GSL_CONFIG="$gsl_prefix/bin/gsl-config"
+     fi
+     if test "x$gsl_exec_prefix" != x ; then
+        GSL_CONFIG="$gsl_exec_prefix/bin/gsl-config"
+     fi
+  fi
+
+  AC_PATH_PROG(GSL_CONFIG, gsl-config, no)
+  min_gsl_version=ifelse([$1], ,0.2.5,$1)
+  AC_MSG_CHECKING(for GSL - version >= $min_gsl_version)
+  no_gsl=""
+  if test "$GSL_CONFIG" = "no" ; then
+    no_gsl=yes
+  else
+    GSL_CFLAGS=`$GSL_CONFIG --cflags`
+    GSL_LIBS=`$GSL_CONFIG --libs`
+
+    gsl_major_version=`$GSL_CONFIG --version | \
+           sed 's/^\([[0-9]]*\).*/\1/'`
+    if test "x${gsl_major_version}" = "x" ; then
+       gsl_major_version=0
+    fi
+
+    gsl_minor_version=`$GSL_CONFIG --version | \
+           sed 's/^\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\).*/\2/'`
+    if test "x${gsl_minor_version}" = "x" ; then
+       gsl_minor_version=0
+    fi
+
+    gsl_micro_version=`$GSL_CONFIG --version | \
+           sed 's/^\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\).*/\3/'`
+    if test "x${gsl_micro_version}" = "x" ; then
+       gsl_micro_version=0
+    fi
+
+    if test "x$enable_gsltest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GSL_CFLAGS"
+      LIBS="$LIBS $GSL_LIBS"
+
+      rm -f conf.gsltest
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char* my_strdup (const char *str);
+
+char*
+my_strdup (const char *str)
+{
+  char *new_str;
+  
+  if (str)
+    {
+      new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
+      strcpy (new_str, str);
+    }
+  else
+    new_str = NULL;
+  
+  return new_str;
+}
+
+int main (void)
+{
+  int major = 0, minor = 0, micro = 0;
+  int n;
+  char *tmp_version;
+
+  system ("touch conf.gsltest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = my_strdup("$min_gsl_version");
+
+  n = sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) ;
+
+  if (n != 2 && n != 3) {
+     printf("%s, bad version string\n", "$min_gsl_version");
+     exit(1);
+   }
+
+   if (($gsl_major_version > major) ||
+      (($gsl_major_version == major) && ($gsl_minor_version > minor)) ||
+      (($gsl_major_version == major) && ($gsl_minor_version == minor) && ($gsl_micro_version >= micro)))
+    {
+      exit(0);
+    }
+  else
+    {
+      printf("\n*** 'gsl-config --version' returned %d.%d.%d, but the minimum version\n", $gsl_major_version, $gsl_minor_version, $gsl_micro_version);
+      printf("*** of GSL required is %d.%d.%d. If gsl-config is correct, then it is\n", major, minor, micro);
+      printf("*** best to upgrade to the required version.\n");
+      printf("*** If gsl-config was wrong, set the environment variable GSL_CONFIG\n");
+      printf("*** to point to the correct copy of gsl-config, and remove the file\n");
+      printf("*** config.cache before re-running configure\n");
+      exit(1);
+    }
+}
+
+],, no_gsl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_gsl" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$GSL_CONFIG" = "no" ; then
+       echo "*** The gsl-config script installed by GSL could not be found"
+       echo "*** If GSL was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GSL_CONFIG environment variable to the"
+       echo "*** full path to gsl-config."
+     else
+       if test -f conf.gsltest ; then
+        :
+       else
+          echo "*** Could not run GSL test program, checking why..."
+          CFLAGS="$CFLAGS $GSL_CFLAGS"
+          LIBS="$LIBS $GSL_LIBS"
+          AC_TRY_LINK([
+#include <stdio.h>
+],      [ return 0; ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GSL or finding the wrong"
+          echo "*** version of GSL. If it is not finding GSL, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+	  echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GSL was incorrectly installed"
+          echo "*** or that you have moved GSL since it was installed. In the latter case, you"
+          echo "*** may want to edit the gsl-config script: $GSL_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+#     GSL_CFLAGS=""
+#     GSL_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GSL_CFLAGS)
+  AC_SUBST(GSL_LIBS)
+  rm -f conf.gsltest
+])
+
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..a401cca
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,8969 @@
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
+[m4_warning([this file was generated for autoconf 2.64.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+  ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool at gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+  lt_cl_success=:
+  test "$silent" = yes &&
+    lt_config_lt_args="$lt_config_lt_args --quiet"
+  exec AS_MESSAGE_LOG_FD>/dev/null
+  $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+  exec AS_MESSAGE_LOG_FD>>config.log
+  $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_XSI_SHELLFNS
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+[$]*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "[$]0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+    [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+       LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+       [shlibpath_overrides_runpath=yes])])
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC*)
+	    # IBM XL 8.0 on PPC
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  linux* | k*bsd*-gnu)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+  ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        AC_LINK_IFELSE(int foo(void) {},
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+        )
+        LDFLAGS="$save_LDFLAGS"
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+        _LT_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+    [[If ld is used when linking, flag to hardcode $libdir into a binary
+    during linking.  This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+    [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+        # as there is no search path for DLLs.
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+        _LT_TAGVAR(always_export_symbols, $1)=no
+        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    cp $export_symbols $output_objdir/$soname.def;
+          else
+	    echo EXPORTS > $output_objdir/$soname.def;
+	    cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          _LT_TAGVAR(ld_shlibs, $1)=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[[12]]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 will use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  xl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='echo'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=echo
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='echo'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${F77-"f77"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${FC-"f95"}
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]+=\$[2]"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+    ;;
+  esac
+])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
+
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
+
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3012 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6])
+m4_define([LT_PACKAGE_REVISION], [1.3012])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6'
+macro_revision='1.3012'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC],		[AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t at _MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+[  --][am_maintainer_other][-maintainer-mode  am_maintainer_other make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer],
+      [USE_MAINTAINER_MODE=$enableval],
+      [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/compile b/compile
new file mode 100755
index 0000000..a81e000
--- /dev/null
+++ b/compile
@@ -0,0 +1,136 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2003-11-09.00
+
+# Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# 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 2, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit 0
+    ;;
+esac
+
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+  case "$1" in
+    -o)
+      # configure might choose to run compile as `compile cc -o foo foo.c'.
+      # So we do something ugly here.
+      ofile=$2
+      shift
+      case "$ofile" in
+	*.o | *.obj)
+	  ;;
+	*)
+	  args="$args -o $ofile"
+	  ofile=
+	  ;;
+      esac
+       ;;
+    *.c)
+      cfile=$1
+      args="$args $1"
+      ;;
+    *)
+      args="$args $1"
+      ;;
+  esac
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+  if mkdir $lockdir > /dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+  mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..278f9e9
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1516 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2007-07-22'
+
+# This file 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:[3456]*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    EM64T | authenticamd)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa:Linux:*:*)
+    	echo xtensa-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..446b020
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,107 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Binary age */
+#undef GFS_BINARY_AGE
+
+/* Compilation flags */
+#undef GFS_COMPILATION_FLAGS
+
+/* Interface age */
+#undef GFS_INTERFACE_AGE
+
+/* Major version */
+#undef GFS_MAJOR_VERSION
+
+/* Micro version */
+#undef GFS_MICRO_VERSION
+
+/* Minor version */
+#undef GFS_MINOR_VERSION
+
+/* Version */
+#undef GFS_VERSION
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fenv.h> header file. */
+#undef HAVE_FENV_H
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the `getopt_long' function. */
+#undef HAVE_GETOPT_LONG
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if gawk and m4 are available. */
+#undef HAVE_M4
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have MPI */
+#undef HAVE_MPI
+
+/* Define to 1 if you have the <netcdf.h> header file. */
+#undef HAVE_NETCDF_H
+
+/* Define to 1 if GModule are supported and if you have pkg-config. */
+#undef HAVE_PKG_CONFIG
+
+/* Define to 1 if you have the <proj_api.h> header file. */
+#undef HAVE_PROJ_API_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Linking flags to build modules. */
+#undef MODULES_FLAGS
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* WaveWatch III version number */
+#undef WW3_VERSION
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..1761d8b
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1626 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2007-06-28'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..f8e57bc
--- /dev/null
+++ b/configure
@@ -0,0 +1,17947 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+$*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "$0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="configure.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+DARCS_CONTROLLED_FALSE
+DARCS_CONTROLLED_TRUE
+GFS2D3_LIBS
+GFS3D_LIBS
+GFS2D_LIBS
+MODULES
+W3INIT
+BUILD_WAVEWATCH_FALSE
+BUILD_WAVEWATCH_TRUE
+BUILD_STOKES_FALSE
+BUILD_STOKES_TRUE
+ac_ct_F77
+FFLAGS
+F77
+BUILD_TIDE_FALSE
+BUILD_TIDE_TRUE
+HAS_NETCDF_FALSE
+HAS_NETCDF_TRUE
+GSL_LIBS
+GSL_CFLAGS
+GSL_CONFIG
+HAS_LIBPROJ_FALSE
+HAS_LIBPROJ_TRUE
+HAVE_MODULES_FALSE
+HAVE_MODULES_TRUE
+have_gmodule
+have_m4
+have_awk
+have_pkg_config
+GTS_DEPLIBS
+gts_libs
+gts_cflags
+GTS_LIBS
+GTS_CFLAGS
+GTS_CONFIG
+NO_UNDEFINED
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+lt_ECHO
+RANLIB
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+use_mpicc
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LT_AGE
+LT_REVISION
+LT_CURRENT
+LT_RELEASE
+GFS_COMPILATION_FLAGS
+GFS_VERSION
+GFS_MICRO_VERSION
+GFS_MINOR_VERSION
+GFS_MAJOR_VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+with_mpicc
+enable_mpi
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+enable_libtool_verbose
+enable_gts_check
+with_gts_prefix
+with_gts_exec_prefix
+enable_gtstest
+enable_modules
+with_gsl_prefix
+with_gsl_exec_prefix
+enable_gsltest
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+F77
+FFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer
+  --disable-mpi           do not compile MPI support
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-libtool-verbose enable verbose libtool output (default disabled)
+  --enable-gts-check      enable object type cast checks in GTS
+  --disable-gtstest       Do not try to compile and run a test GTS program
+  --disable-modules       link modules statically with the executables
+  --disable-gsltest       Do not try to compile and run a test GSL program
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-mpicc=path       pick a specific path to mpicc
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-gts-prefix=PFX   Prefix where GTS is installed (optional)
+  --with-gts-exec-prefix=PFX Exec prefix where GTS is installed (optional)
+  --with-gsl-prefix=PFX   Prefix where GSL is installed (optional)
+  --with-gsl-exec-prefix=PFX Exec prefix where GSL is installed (optional)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_f77_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_f77_try_compile
+
+# ac_fn_f77_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_f77_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+#AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
+# Making releases:
+#   GFS_MICRO_VERSION += 1;
+#   GFS_INTERFACE_AGE += 1;
+#   GFS_BINARY_AGE += 1;
+# if any functions have been added, set GFS_INTERFACE_AGE to 0.
+# if backwards compatibility has been broken,
+# set GFS_BINARY_AGE and GFS_INTERFACE_AGE to 0.
+#
+# Remember to update rpm/gerris.spec when changing the version number.
+GFS_MAJOR_VERSION=1
+GFS_MINOR_VERSION=3
+GFS_MICRO_VERSION=2
+GFS_INTERFACE_AGE=0
+GFS_BINARY_AGE=0
+GFS_VERSION=$GFS_MAJOR_VERSION.$GFS_MINOR_VERSION.$GFS_MICRO_VERSION
+GFS_COMPILATION_FLAGS=$CFLAGS
+#AC_DIVERT_POP()dnl
+
+
+
+
+
+
+
+# libtool versioning
+LT_RELEASE=$GFS_MAJOR_VERSION.$GFS_MINOR_VERSION
+LT_CURRENT=`expr $GFS_MICRO_VERSION - $GFS_INTERFACE_AGE`
+LT_REVISION=$GFS_INTERFACE_AGE
+LT_AGE=`expr $GFS_BINARY_AGE - $GFS_INTERFACE_AGE`
+
+
+
+
+
+# For automake.
+VERSION=$GFS_VERSION
+PACKAGE=gerris
+
+am__api_version='1.11'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    test -d ./--version && rmdir ./--version
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=$PACKAGE
+ VERSION=$VERSION
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Specify a configuration file
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_MAJOR_VERSION $GFS_MAJOR_VERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_MINOR_VERSION $GFS_MINOR_VERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_MICRO_VERSION $GFS_MICRO_VERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_INTERFACE_AGE $GFS_INTERFACE_AGE
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_BINARY_AGE $GFS_BINARY_AGE
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_VERSION "$GFS_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GFS_COMPILATION_FLAGS "$GFS_COMPILATION_FLAGS"
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+# Check whether --with-mpicc was given.
+if test "${with_mpicc+set}" = set; then :
+  withval=$with_mpicc; with_mpicc=$withval
+else
+  with_mpicc=''
+fi
+
+
+# check if MPI support is disabled
+# Check whether --enable-mpi was given.
+if test "${enable_mpi+set}" = set; then :
+  enableval=$enable_mpi;  case "${enableval}" in
+	yes) ;;
+	*) with_mpicc=no ;;
+  esac
+fi
+
+
+if test "x$with_mpicc" != "xno" ; then
+  if test "x$with_mpicc" != "x" ; then
+     if test -x "$with_mpicc" ; then
+       use_mpicc=yes
+       CC="$with_mpicc"
+     fi
+  else
+     # Extract the first word of "mpicc", so it can be a program name with args.
+set dummy mpicc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_use_mpicc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$use_mpicc"; then
+  ac_cv_prog_use_mpicc="$use_mpicc" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_use_mpicc="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+use_mpicc=$ac_cv_prog_use_mpicc
+if test -n "$use_mpicc"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_mpicc" >&5
+$as_echo "$use_mpicc" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+     if test "x$use_mpicc" = "xyes" ; then
+       CC=mpicc
+     fi
+  fi
+  if test "x$use_mpicc" = "xyes" ; then
+
+$as_echo "#define HAVE_MPI 1" >>confdefs.h
+
+  else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: MPI not found. No MPI support will be compiled in." >&5
+$as_echo "$as_me: WARNING: MPI not found. No MPI support will be compiled in." >&2;}
+  fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+if test x$GCC = xyes ; then
+  CFLAGS="$CFLAGS -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -Wmissing-declarations -pipe"
+fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AS+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AS="${ac_tool_prefix}as"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+  ac_ct_AS=$AS
+  # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AS+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AS"; then
+  ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AS="as"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AS" = x; then
+    AS="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AS=$ac_ct_AS
+  fi
+else
+  AS="$ac_cv_prog_AS"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+  ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6'
+macro_revision='1.3012'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:5072: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:5075: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:5078: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 6281 "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:7805: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:7809: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8144: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:8148: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8249: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:8253: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:8304: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:8308: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec=
+	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec='$convenience'
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_from_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  whole_archive_flag_spec=''
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld='+b $libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LDFLAGS="$save_LDFLAGS"
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+	pic_flag=$lt_prog_compiler_pic
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        then
+	  archive_cmds_need_lc=no
+        else
+	  archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 10687 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 10783 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Check whether --enable-libtool-verbose was given.
+if test "${enable_libtool_verbose+set}" = set; then :
+  enableval=$enable_libtool_verbose; with_libtool_verbose=$enableval
+else
+  with_libtool_verbose='no'
+fi
+
+if test "$with_libtool_verbose" = 'no'
+then
+  LIBTOOL="$LIBTOOL --silent"
+fi
+
+case "$build" in
+  *-apple-darwin*) NO_UNDEFINED="" ;;
+  *-pc-cygwin*)    NO_UNDEFINED="" ;;
+  *)               NO_UNDEFINED="-no-undefined" ;;
+esac
+
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if test "${ac_cv_search_strerror+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_strerror+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_strerror+set}" = set; then :
+
+else
+  ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+
+# check that pointers can be stored in doubles
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pointers can be stored in doubles" >&5
+$as_echo_n "checking whether pointers can be stored in doubles... " >&6; }
+if test "$cross_compiling" = yes; then :
+  can_store_pointers=yes; echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+main () {
+  if (sizeof (void *) > sizeof (double))
+    return 1;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  can_store_pointers=yes
+else
+  can_store_pointers=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_store_pointers" >&5
+$as_echo "$can_store_pointers" >&6; }
+if test x$can_store_pointers = xno ; then
+  as_fn_error "
+*** Pointers cannot be stored in doubles on this architecture." "$LINENO" 5
+fi
+
+# check if we want to enable GTS casts checks
+# Check whether --enable-gts-check was given.
+if test "${enable_gts_check+set}" = set; then :
+  enableval=$enable_gts_check;  case "${enableval}" in
+	*) gts_check_casts="--check" ;;
+  esac
+fi
+
+
+if test x$with_gts = xyes ; then
+  as_fn_error "
+*** Directory must be specified for --with-gts" "$LINENO" 5
+fi
+
+if test x$with_gts = x ; then
+  # Look for separately installed gts
+
+
+# Check whether --with-gts-prefix was given.
+if test "${with_gts_prefix+set}" = set; then :
+  withval=$with_gts_prefix; gts_config_prefix="$withval"
+else
+  gts_config_prefix=""
+fi
+
+
+# Check whether --with-gts-exec-prefix was given.
+if test "${with_gts_exec_prefix+set}" = set; then :
+  withval=$with_gts_exec_prefix; gts_config_exec_prefix="$withval"
+else
+  gts_config_exec_prefix=""
+fi
+
+# Check whether --enable-gtstest was given.
+if test "${enable_gtstest+set}" = set; then :
+  enableval=$enable_gtstest;
+else
+  enable_gtstest=yes
+fi
+
+
+  if test x$gts_config_exec_prefix != x ; then
+     gts_config_args="$gts_config_args --exec-prefix=$gts_config_exec_prefix"
+     if test x${GTS_CONFIG+set} != xset ; then
+        GTS_CONFIG=$gts_config_exec_prefix/bin/gts-config
+     fi
+  fi
+  if test x$gts_config_prefix != x ; then
+     gts_config_args="$gts_config_args --prefix=$gts_config_prefix"
+     if test x${GTS_CONFIG+set} != xset ; then
+        GTS_CONFIG=$gts_config_prefix/bin/gts-config
+     fi
+  fi
+
+  for module in .
+  do
+      case "$module" in
+         gmodule)
+             gts_config_args="$gts_config_args gmodule"
+         ;;
+         gthread)
+             gts_config_args="$gts_config_args gthread"
+         ;;
+      esac
+  done
+
+  # Extract the first word of "gts-config", so it can be a program name with args.
+set dummy gts-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GTS_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GTS_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GTS_CONFIG="$GTS_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GTS_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_GTS_CONFIG" && ac_cv_path_GTS_CONFIG="no"
+  ;;
+esac
+fi
+GTS_CONFIG=$ac_cv_path_GTS_CONFIG
+if test -n "$GTS_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTS_CONFIG" >&5
+$as_echo "$GTS_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  min_gts_version=0.7.4
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTS - version >= $min_gts_version" >&5
+$as_echo_n "checking for GTS - version >= $min_gts_version... " >&6; }
+  no_gts=""
+  if test "$GTS_CONFIG" = "no" ; then
+    no_gts=yes
+  else
+    GTS_CFLAGS=`$GTS_CONFIG $gts_config_args --cflags`
+    GTS_LIBS=`$GTS_CONFIG $gts_config_args --libs`
+    gts_config_major_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+    gts_config_minor_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+    gts_config_micro_version=`$GTS_CONFIG $gts_config_args --version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+    if test "x$enable_gtstest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GTS_CFLAGS"
+      LIBS="$GTS_LIBS $LIBS"
+      rm -f conf.gtstest
+      if test "$cross_compiling" = yes; then :
+  echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <gts.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  system ("touch conf.gtstest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = g_strdup("$min_gts_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_gts_version");
+     exit(1);
+   }
+
+  if ((gts_major_version != $gts_config_major_version) ||
+      (gts_minor_version != $gts_config_minor_version) ||
+      (gts_micro_version != $gts_config_micro_version))
+    {
+      printf("\n*** 'gts-config --version' returned %d.%d.%d, but GTS (%d.%d.%d)\n",
+             $gts_config_major_version, $gts_config_minor_version, $gts_config_micro_version,
+             gts_major_version, gts_minor_version, gts_micro_version);
+      printf ("*** was found! If gts-config was correct, then it is best\n");
+      printf ("*** to remove the old version of GTS. You may also be able to fix the error\n");
+      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+      printf("*** required on your system.\n");
+      printf("*** If gts-config was wrong, set the environment variable GTS_CONFIG\n");
+      printf("*** to point to the correct copy of gts-config, and remove the file config.cache\n");
+      printf("*** before re-running configure\n");
+    }
+  else if ((gts_major_version != GTS_MAJOR_VERSION) ||
+	   (gts_minor_version != GTS_MINOR_VERSION) ||
+           (gts_micro_version != GTS_MICRO_VERSION))
+    {
+      printf("*** GTS header files (version %d.%d.%d) do not match\n",
+	     GTS_MAJOR_VERSION, GTS_MINOR_VERSION, GTS_MICRO_VERSION);
+      printf("*** library (version %d.%d.%d)\n",
+	     gts_major_version, gts_minor_version, gts_micro_version);
+    }
+  else
+    {
+      if ((gts_major_version > major) ||
+        ((gts_major_version == major) && (gts_minor_version > minor)) ||
+        ((gts_major_version == major) && (gts_minor_version == minor) && (gts_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of GTS (%d.%d.%d) was found.\n",
+               gts_major_version, gts_minor_version, gts_micro_version);
+        printf("*** You need a version of GTS newer than %d.%d.%d. The latest version of\n",
+	       major, minor, micro);
+        printf("*** GTS is always available from http://gts.sourceforge.net.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the gts-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of GTS, but you can also set the GTS_CONFIG environment to point to the\n");
+        printf("*** correct copy of gts-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+      }
+    }
+  return 1;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  no_gts=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_gts" = x ; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+     :
+  else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+     if test "$GTS_CONFIG" = "no" ; then
+       echo "*** The gts-config script installed by GTS could not be found"
+       echo "*** If GTS was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GTS_CONFIG environment variable to the"
+       echo "*** full path to gts-config."
+     else
+       if test -f conf.gtstest ; then
+        :
+       else
+          echo "*** Could not run GTS test program, checking why..."
+          CFLAGS="$CFLAGS $GTS_CFLAGS"
+          LIBS="$LIBS $GTS_LIBS"
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <gts.h>
+#include <stdio.h>
+
+int
+main ()
+{
+ return ((gts_major_version) || (gts_minor_version) || (gts_micro_version));
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+   echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GTS or finding the wrong"
+          echo "*** version of GTS. If it is not finding GTS, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+	  echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+          echo "***"
+else
+   echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GTS was incorrectly installed"
+          echo "*** or that you have moved GTS since it was installed. In the latter case, you"
+          echo "*** may want to edit the gts-config script: $GTS_CONFIG"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     GTS_CFLAGS=""
+     GTS_LIBS=""
+     as_fn_error "
+*** GTS 0.7.4 or better is required. The latest version of GTS
+*** is always available from http://gts.sourceforge.net." "$LINENO" 5
+  fi
+
+
+  rm -f conf.gtstest
+
+
+  gts_cflags=`$GTS_CONFIG --cflags $gts_check_casts gmodule`
+  gts_libs=`$GTS_CONFIG --libs gmodule`
+  GTS_LIBS="$gts_libs"
+  GTS_DEPLIBS="$gts_libs"
+else
+  # Use uninstalled gts (assume they got the version right)
+
+  GTS_CONFIG=$with_gts/gts-config
+  if test -x $GTS_CONFIG ; then
+    :
+  else
+    as_fn_error "GTS directory ($with_gts) not present or not configured" "$LINENO" 5
+  fi
+
+  # For use in gfs-config
+  gts_cflags=`$GTS_CONFIG --cflags $gts_check_casts gmodule`
+  gts_libs=`$GTS_CONFIG --libs gmodule`
+  gts_release=`$GTS_CONFIG --version | sed 's%\\.[0-9]*$%%'`
+
+  # canonicalize relative paths
+  case $with_gts in
+    /*)
+      gts_dir=$with_gts
+      ;;
+    *)
+      gts_dir="\$(top_builddir)/$with_gts"
+      ;;
+  esac
+
+  GTS_CFLAGS="-I$gts_dir"
+  if test -n "$gts_check_casts"; then
+	 GTS_CFLAGS="$GTS_CFLAGS -DGTS_CHECK_CASTS"
+  fi
+  GTS_LIBS="$gts_dir/libgts.la"
+  GTS_DEPLIBS=
+
+
+fi
+
+if test -n "$gts_check_casts"; then
+  GTS_CFLAGS="$GTS_CFLAGS -DGTS_CHECK_CASTS"
+fi
+
+
+
+
+
+# check whether GModules are supported
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether modules are supported" >&5
+$as_echo_n "checking whether modules are supported... " >&6; }
+OLD_CFLAGS=$CFLAGS
+CFLAGS=$gts_cflags
+OLD_LIBS=$LIBS
+LIBS=$gts_libs
+if test "$cross_compiling" = yes; then :
+  have_gmodule=yes; echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <glib.h>
+#include <gmodule.h>
+
+main () {
+  if (!g_module_supported ())
+    return 1;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  have_gmodule=yes
+else
+  have_gmodule=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gmodule" >&5
+$as_echo "$have_gmodule" >&6; }
+CFLAGS=$OLD_CFLAGS
+LIBS=$OLD_LIBS
+
+# checking how to build modules
+if test "$have_gmodule" = "yes"; then
+   module_flags=""
+   for flags in \
+       "-fPIC -shared -x c" \
+       "-fPIC -dynamiclib -x c -undefined dynamic_lookup" \
+       "-fPIC -bundle -x c"
+   do
+	if test x"$module_flags" = x; then
+	   if echo "test(){}" | gcc $flags - 2> /dev/null; then
+	      module_flags=\"$flags\"
+	   fi
+	fi
+   done
+   if test x"$module_flags" = x; then
+	have_gmodule=no
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not build module, functions in parameter files will not be supported." >&5
+$as_echo "$as_me: WARNING: Could not build module, functions in parameter files will not be supported." >&2;}
+   fi
+
+cat >>confdefs.h <<_ACEOF
+#define MODULES_FLAGS $module_flags
+_ACEOF
+
+fi
+
+# checks for pkg-config
+if test "$have_gmodule" = "yes"; then
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_have_pkg_config+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$have_pkg_config"; then
+  ac_cv_prog_have_pkg_config="$have_pkg_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_have_pkg_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_have_pkg_config" && ac_cv_prog_have_pkg_config="no"
+fi
+fi
+have_pkg_config=$ac_cv_prog_have_pkg_config
+if test -n "$have_pkg_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pkg_config" >&5
+$as_echo "$have_pkg_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test "$have_pkg_config" = "no"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config is required for functions in parameter files." >&5
+$as_echo "$as_me: WARNING: pkg-config is required for functions in parameter files." >&2;}
+  fi
+fi
+if test x"$have_pkg_config" = x"yes"; then
+
+$as_echo "#define HAVE_PKG_CONFIG 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_PKG_CONFIG 0" >>confdefs.h
+
+fi
+
+# checks for gawk and m4
+# Extract the first word of "gawk", so it can be a program name with args.
+set dummy gawk; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_have_awk+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$have_awk"; then
+  ac_cv_prog_have_awk="$have_awk" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_have_awk="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_have_awk" && ac_cv_prog_have_awk="no"
+fi
+fi
+have_awk=$ac_cv_prog_have_awk
+if test -n "$have_awk"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_awk" >&5
+$as_echo "$have_awk" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$have_awk" = "yes"; then
+   # Extract the first word of "m4", so it can be a program name with args.
+set dummy m4; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_have_m4+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$have_m4"; then
+  ac_cv_prog_have_m4="$have_m4" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_have_m4="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_have_m4" && ac_cv_prog_have_m4="no"
+fi
+fi
+have_m4=$ac_cv_prog_have_m4
+if test -n "$have_m4"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_m4" >&5
+$as_echo "$have_m4" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+   if test "$have_m4" = "yes"; then
+
+$as_echo "#define HAVE_M4 1" >>confdefs.h
+
+   else
+      $as_echo "#define HAVE_M4 0" >>confdefs.h
+
+   fi
+fi
+
+# check if module support is disabled
+# Check whether --enable-modules was given.
+if test "${enable_modules+set}" = set; then :
+  enableval=$enable_modules;  case "${enableval}" in
+	yes) ;;
+	*) have_gmodule=no ;;
+  esac
+fi
+
+
+
+ if test "$have_gmodule" = "yes"; then
+  HAVE_MODULES_TRUE=
+  HAVE_MODULES_FALSE='#'
+else
+  HAVE_MODULES_TRUE='#'
+  HAVE_MODULES_FALSE=
+fi
+
+
+
+
+
+
+# checks for libproj
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pj_fwd in -lproj" >&5
+$as_echo_n "checking for pj_fwd in -lproj... " >&6; }
+if test "${ac_cv_lib_proj_pj_fwd+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lproj -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pj_fwd ();
+int
+main ()
+{
+return pj_fwd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_proj_pj_fwd=yes
+else
+  ac_cv_lib_proj_pj_fwd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_proj_pj_fwd" >&5
+$as_echo "$ac_cv_lib_proj_pj_fwd" >&6; }
+if test "x$ac_cv_lib_proj_pj_fwd" = x""yes; then :
+  proj="true"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libproj not found. Map module will not be available." >&5
+$as_echo "$as_me: WARNING: libproj not found. Map module will not be available." >&2;}
+fi
+
+for ac_header in proj_api.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "proj_api.h" "ac_cv_header_proj_api_h" "$ac_includes_default"
+if test "x$ac_cv_header_proj_api_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PROJ_API_H 1
+_ACEOF
+ proj="true"
+else
+  proj="false"
+fi
+
+done
+
+ if test x$proj = xtrue; then
+  HAS_LIBPROJ_TRUE=
+  HAS_LIBPROJ_FALSE='#'
+else
+  HAS_LIBPROJ_TRUE='#'
+  HAS_LIBPROJ_FALSE=
+fi
+
+
+# checks for GNU Scientific Library
+
+
+# Check whether --with-gsl-prefix was given.
+if test "${with_gsl_prefix+set}" = set; then :
+  withval=$with_gsl_prefix; gsl_prefix="$withval"
+else
+  gsl_prefix=""
+fi
+
+
+# Check whether --with-gsl-exec-prefix was given.
+if test "${with_gsl_exec_prefix+set}" = set; then :
+  withval=$with_gsl_exec_prefix; gsl_exec_prefix="$withval"
+else
+  gsl_exec_prefix=""
+fi
+
+# Check whether --enable-gsltest was given.
+if test "${enable_gsltest+set}" = set; then :
+  enableval=$enable_gsltest;
+else
+  enable_gsltest=yes
+fi
+
+
+  if test "x${GSL_CONFIG+set}" != xset ; then
+     if test "x$gsl_prefix" != x ; then
+         GSL_CONFIG="$gsl_prefix/bin/gsl-config"
+     fi
+     if test "x$gsl_exec_prefix" != x ; then
+        GSL_CONFIG="$gsl_exec_prefix/bin/gsl-config"
+     fi
+  fi
+
+  # Extract the first word of "gsl-config", so it can be a program name with args.
+set dummy gsl-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GSL_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GSL_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GSL_CONFIG="$GSL_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GSL_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_GSL_CONFIG" && ac_cv_path_GSL_CONFIG="no"
+  ;;
+esac
+fi
+GSL_CONFIG=$ac_cv_path_GSL_CONFIG
+if test -n "$GSL_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSL_CONFIG" >&5
+$as_echo "$GSL_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  min_gsl_version=0.2.5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSL - version >= $min_gsl_version" >&5
+$as_echo_n "checking for GSL - version >= $min_gsl_version... " >&6; }
+  no_gsl=""
+  if test "$GSL_CONFIG" = "no" ; then
+    no_gsl=yes
+  else
+    GSL_CFLAGS=`$GSL_CONFIG --cflags`
+    GSL_LIBS=`$GSL_CONFIG --libs`
+
+    gsl_major_version=`$GSL_CONFIG --version | \
+           sed 's/^\([0-9]*\).*/\1/'`
+    if test "x${gsl_major_version}" = "x" ; then
+       gsl_major_version=0
+    fi
+
+    gsl_minor_version=`$GSL_CONFIG --version | \
+           sed 's/^\([0-9]*\)\.\{0,1\}\([0-9]*\).*/\2/'`
+    if test "x${gsl_minor_version}" = "x" ; then
+       gsl_minor_version=0
+    fi
+
+    gsl_micro_version=`$GSL_CONFIG --version | \
+           sed 's/^\([0-9]*\)\.\{0,1\}\([0-9]*\)\.\{0,1\}\([0-9]*\).*/\3/'`
+    if test "x${gsl_micro_version}" = "x" ; then
+       gsl_micro_version=0
+    fi
+
+    if test "x$enable_gsltest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GSL_CFLAGS"
+      LIBS="$LIBS $GSL_LIBS"
+
+      rm -f conf.gsltest
+      if test "$cross_compiling" = yes; then :
+  echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char* my_strdup (const char *str);
+
+char*
+my_strdup (const char *str)
+{
+  char *new_str;
+
+  if (str)
+    {
+      new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
+      strcpy (new_str, str);
+    }
+  else
+    new_str = NULL;
+
+  return new_str;
+}
+
+int main (void)
+{
+  int major = 0, minor = 0, micro = 0;
+  int n;
+  char *tmp_version;
+
+  system ("touch conf.gsltest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = my_strdup("$min_gsl_version");
+
+  n = sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) ;
+
+  if (n != 2 && n != 3) {
+     printf("%s, bad version string\n", "$min_gsl_version");
+     exit(1);
+   }
+
+   if (($gsl_major_version > major) ||
+      (($gsl_major_version == major) && ($gsl_minor_version > minor)) ||
+      (($gsl_major_version == major) && ($gsl_minor_version == minor) && ($gsl_micro_version >= micro)))
+    {
+      exit(0);
+    }
+  else
+    {
+      printf("\n*** 'gsl-config --version' returned %d.%d.%d, but the minimum version\n", $gsl_major_version, $gsl_minor_version, $gsl_micro_version);
+      printf("*** of GSL required is %d.%d.%d. If gsl-config is correct, then it is\n", major, minor, micro);
+      printf("*** best to upgrade to the required version.\n");
+      printf("*** If gsl-config was wrong, set the environment variable GSL_CONFIG\n");
+      printf("*** to point to the correct copy of gsl-config, and remove the file\n");
+      printf("*** config.cache before re-running configure\n");
+      exit(1);
+    }
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  no_gsl=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_gsl" = x ; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+     :
+  else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+     if test "$GSL_CONFIG" = "no" ; then
+       echo "*** The gsl-config script installed by GSL could not be found"
+       echo "*** If GSL was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GSL_CONFIG environment variable to the"
+       echo "*** full path to gsl-config."
+     else
+       if test -f conf.gsltest ; then
+        :
+       else
+          echo "*** Could not run GSL test program, checking why..."
+          CFLAGS="$CFLAGS $GSL_CFLAGS"
+          LIBS="$LIBS $GSL_LIBS"
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+   echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GSL or finding the wrong"
+          echo "*** version of GSL. If it is not finding GSL, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+	  echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+else
+   echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GSL was incorrectly installed"
+          echo "*** or that you have moved GSL since it was installed. In the latter case, you"
+          echo "*** may want to edit the gsl-config script: $GSL_CONFIG"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+#     GSL_CFLAGS=""
+#     GSL_LIBS=""
+     :
+  fi
+
+
+  rm -f conf.gsltest
+
+
+# checks for netCDF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nc_open in -lnetcdf" >&5
+$as_echo_n "checking for nc_open in -lnetcdf... " >&6; }
+if test "${ac_cv_lib_netcdf_nc_open+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetcdf -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nc_open ();
+int
+main ()
+{
+return nc_open ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_netcdf_nc_open=yes
+else
+  ac_cv_lib_netcdf_nc_open=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netcdf_nc_open" >&5
+$as_echo "$ac_cv_lib_netcdf_nc_open" >&6; }
+if test "x$ac_cv_lib_netcdf_nc_open" = x""yes; then :
+  netcdf="true"
+else
+  netcdf="false"
+fi
+
+for ac_header in netcdf.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "netcdf.h" "ac_cv_header_netcdf_h" "$ac_includes_default"
+if test "x$ac_cv_header_netcdf_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NETCDF_H 1
+_ACEOF
+ netcdf="true"
+else
+  netcdf="false"
+fi
+
+done
+
+ if test x$netcdf = xtrue; then
+  HAS_NETCDF_TRUE=
+  HAS_NETCDF_FALSE='#'
+else
+  HAS_NETCDF_TRUE='#'
+  HAS_NETCDF_FALSE=
+fi
+
+
+# Tide module requires both netCDF and GSL
+if test x$netcdf = xfalse -o x$no_gsl = xyes; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GSL and/or netCDF not found. Tide module will not be available." >&5
+$as_echo "$as_me: WARNING: GSL and/or netCDF not found. Tide module will not be available." >&2;}
+fi
+ if test x$netcdf = xtrue -a x$no_gsl = x; then
+  BUILD_TIDE_TRUE=
+  BUILD_TIDE_FALSE='#'
+else
+  BUILD_TIDE_TRUE='#'
+  BUILD_TIDE_FALSE=
+fi
+
+
+# Stokes module requires a fortran compiler
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_F77="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_F77" && break
+done
+
+  if test "x$ac_ct_F77" = x; then
+    F77=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    F77=$ac_ct_F77
+  fi
+fi
+
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if test "${ac_cv_prog_f77_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  FFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_cv_prog_f77_g=yes
+else
+  ac_cv_prog_f77_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+  G77=yes
+else
+  G77=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_F77="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_F77" && break
+done
+
+  if test "x$ac_ct_F77" = x; then
+    F77=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    F77=$ac_ct_F77
+  fi
+fi
+
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    rm -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if test "${ac_cv_prog_f77_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  FFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+  ac_cv_prog_f77_g=yes
+else
+  ac_cv_prog_f77_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+  G77=yes
+else
+  G77=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+
+
+      ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_direct_absolute_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_flag_spec_ld_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+inherit_rpath_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${F77-"f77"}
+  compiler=$CC
+  compiler_F77=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  GCC=$G77
+  if test -n "$compiler"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[4-9]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+    GCC_F77="$G77"
+    LD_F77="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_F77='-Wl,'
+    lt_prog_compiler_static_F77='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_F77='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_F77='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_F77=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_F77='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_F77=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic_F77='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      else
+	lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-KPIC'
+	lt_prog_compiler_static_F77='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-fPIC'
+	lt_prog_compiler_static_F77='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='--shared'
+	lt_prog_compiler_static_F77='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-fpic'
+	lt_prog_compiler_static_F77='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_F77='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_F77='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-qpic'
+	lt_prog_compiler_static_F77='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic_F77='-KPIC'
+	  lt_prog_compiler_static_F77='-Bstatic'
+	  lt_prog_compiler_wl_F77='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic_F77='-KPIC'
+	  lt_prog_compiler_static_F77='-Bstatic'
+	  lt_prog_compiler_wl_F77=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_F77='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl_F77='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl_F77='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_F77='-Qoption ld '
+      lt_prog_compiler_pic_F77='-PIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic_F77='-Kconform_pic'
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_F77='-pic'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_F77=
+    ;;
+  *)
+    lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_F77" >&5
+$as_echo "$lt_prog_compiler_pic_F77" >&6; }
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_F77=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_F77"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13112: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:13116: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_F77=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_F77" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_F77" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then
+    case $lt_prog_compiler_pic_F77 in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+     esac
+else
+    lt_prog_compiler_pic_F77=
+     lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_F77=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_F77=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_F77=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_F77" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_F77" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then
+    :
+else
+    lt_prog_compiler_static_F77=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13211: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13215: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13263: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13267: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag_F77=
+  always_export_symbols_F77=no
+  archive_cmds_F77=
+  archive_expsym_cmds_F77=
+  compiler_needs_object_F77=no
+  enable_shared_with_static_runtimes_F77=no
+  export_dynamic_flag_spec_F77=
+  export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic_F77=no
+  hardcode_direct_F77=no
+  hardcode_direct_absolute_F77=no
+  hardcode_libdir_flag_spec_F77=
+  hardcode_libdir_flag_spec_ld_F77=
+  hardcode_libdir_separator_F77=
+  hardcode_minus_L_F77=no
+  hardcode_shlibpath_var_F77=unsupported
+  inherit_rpath_F77=no
+  link_all_deplibs_F77=unknown
+  module_cmds_F77=
+  module_expsym_cmds_F77=
+  old_archive_from_new_cmds_F77=
+  old_archive_from_expsyms_cmds_F77=
+  thread_safe_flag_spec_F77=
+  whole_archive_flag_spec_F77=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_F77=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu)
+    link_all_deplibs_F77=no
+    ;;
+  esac
+
+  ld_shlibs_F77=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec_F77=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs_F77=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds_F77=''
+        ;;
+      m68k)
+            archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec_F77='-L$libdir'
+            hardcode_minus_L_F77=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag_F77=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=no
+      enable_shared_with_static_runtimes_F77=yes
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_F77='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec_F77=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object_F77=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec_F77='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec_F77=
+	  hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
+	  archive_cmds_F77='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs_F77=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs_F77=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs_F77=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+	    archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs_F77=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_F77" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec_F77=
+      export_dynamic_flag_spec_F77=
+      whole_archive_flag_spec_F77=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=yes
+      archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_F77=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct_F77=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_F77=''
+      hardcode_direct_F77=yes
+      hardcode_direct_absolute_F77=yes
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+      file_list_spec_F77='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct_F77=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L_F77=yes
+	  hardcode_libdir_flag_spec_F77='-L$libdir'
+	  hardcode_libdir_separator_F77=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs_F77=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec_F77='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_F77=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag_F77='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds_F77='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag_F77="-z nodefs"
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag_F77=' ${wl}-bernotok'
+	  allow_undefined_flag_F77=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec_F77='$convenience'
+	  archive_cmds_need_lc_F77=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds_F77=''
+        ;;
+      m68k)
+            archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec_F77='-L$libdir'
+            hardcode_minus_L_F77=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec_F77=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_F77=' '
+      allow_undefined_flag_F77=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_from_new_cmds_F77='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_F77=yes
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_F77=no
+  hardcode_direct_F77=no
+  hardcode_automatic_F77=yes
+  hardcode_shlibpath_var_F77=unsupported
+  whole_archive_flag_spec_F77=''
+  link_all_deplibs_F77=yes
+  allow_undefined_flag_F77="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs_F77=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_F77=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds_F77='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_direct_F77=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld_F77='+b $libdir'
+	hardcode_libdir_separator_F77=:
+	hardcode_direct_F77=yes
+	hardcode_direct_absolute_F77=yes
+	export_dynamic_flag_spec_F77='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L_F77=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_F77=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct_F77=no
+	  hardcode_shlibpath_var_F77=no
+	  ;;
+	*)
+	  hardcode_direct_F77=yes
+	  hardcode_direct_absolute_F77=yes
+	  export_dynamic_flag_spec_F77='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_F77=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        cat > conftest.$ac_ext <<_ACEOF
+int foo(void) {}
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LDFLAGS="$save_LDFLAGS"
+      else
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc_F77='no'
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      inherit_rpath_F77=yes
+      link_all_deplibs_F77=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    newsos6)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct_F77=yes
+	hardcode_shlibpath_var_F77=no
+	hardcode_direct_absolute_F77=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec_F77='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec_F77='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      allow_undefined_flag_F77=unsupported
+      archive_cmds_F77='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc_F77='no'
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec_F77='-rpath $libdir'
+      fi
+      archive_cmds_need_lc_F77='no'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    solaris*)
+      no_undefined_flag_F77=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds_F77='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds_F77='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_shlibpath_var_F77=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs_F77=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds_F77='$CC -r -o $output$reload_objs'
+	  hardcode_direct_F77=no
+        ;;
+	motorola)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var_F77=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs_F77=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_F77='${wl}-z,text'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_F77='${wl}-z,text'
+      allow_undefined_flag_F77='${wl}-z,nodefs'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='${wl}-R,$libdir'
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      ld_shlibs_F77=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec_F77='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_F77" >&5
+$as_echo "$ld_shlibs_F77" >&6; }
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+with_gnu_ld_F77=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_F77=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_F77 in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_F77
+	pic_flag=$lt_prog_compiler_pic_F77
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+        allow_undefined_flag_F77=
+        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        then
+	  archive_cmds_need_lc_F77=no
+        else
+	  archive_cmds_need_lc_F77=yes
+        fi
+        allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_F77" >&5
+$as_echo "$archive_cmds_need_lc_F77" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_F77\"; \
+       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_F77\""
+  cat > conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+if ac_fn_f77_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" ||
+   test -n "$runpath_var_F77" ||
+   test "X$hardcode_automatic_F77" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_F77" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+     test "$hardcode_minus_L_F77" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_F77=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_F77=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_F77=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_F77" >&5
+$as_echo "$hardcode_action_F77" >&6; }
+
+if test "$hardcode_action_F77" = relink ||
+   test "$inherit_rpath_F77" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test x$F77 != x; then
+  BUILD_STOKES_TRUE=
+  BUILD_STOKES_FALSE='#'
+else
+  BUILD_STOKES_TRUE='#'
+  BUILD_STOKES_FALSE=
+fi
+
+
+# Build wavewatch module if wavewatch is installed
+ if test -r $HOME/.wwatch3.env; then
+  BUILD_WAVEWATCH_TRUE=
+  BUILD_WAVEWATCH_FALSE='#'
+else
+  BUILD_WAVEWATCH_TRUE='#'
+  BUILD_WAVEWATCH_FALSE=
+fi
+
+if test -r $HOME/.wwatch3.env; then
+   ww3_dir=`grep WWATCH3_DIR $HOME/.wwatch3.env | awk '{print $2}'`
+   ww3_version=`grep "WWVER  = " $ww3_dir/ftn/*.ftn | \
+                awk '{print substr($(NF-1),2)}' | \
+                sed 's/\.//'`
+   W3INIT="w3init$ww3_version"
+
+
+cat >>confdefs.h <<_ACEOF
+#define WW3_VERSION $ww3_version
+_ACEOF
+
+fi
+
+for ac_header in fenv.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fenv.h" "ac_cv_header_fenv_h" "$ac_includes_default"
+if test "x$ac_cv_header_fenv_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FENV_H 1
+_ACEOF
+ $as_echo "#define HAVE_FENV_H 1" >>confdefs.h
+
+fi
+
+done
+
+for ac_header in unistd.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_UNISTD_H 1
+_ACEOF
+ $as_echo "#define HAVE_UNISTD_H 1" >>confdefs.h
+
+fi
+
+done
+
+for ac_header in getopt.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "getopt.h" "ac_cv_header_getopt_h" "$ac_includes_default"
+if test "x$ac_cv_header_getopt_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETOPT_H 1
+_ACEOF
+ $as_echo "#define HAVE_GETOPT_H 1" >>confdefs.h
+
+fi
+
+done
+
+
+for ac_func in getopt_long
+do :
+  ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
+if test "x$ac_cv_func_getopt_long" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETOPT_LONG 1
+_ACEOF
+
+fi
+done
+
+
+ac_config_commands="$ac_config_commands default-1"
+
+
+ac_config_commands="$ac_config_commands default-2"
+
+
+MODULES=""
+if test "$have_gmodule" = "no"; then
+  for file in `ls modules/*.mod`; do
+	name=`basename $file .mod`
+	MODULES=" $MODULES ../modules/$name.o"
+  done
+fi
+
+GFS2D_LIBS="\$(top_builddir)/src/libgfs2D.la $GTS_LIBS $MODULES"
+GFS3D_LIBS="\$(top_builddir)/src/libgfs3D.la $GTS_LIBS $MODULES"
+GFS2D3_LIBS="\$(top_builddir)/src/libgfs2D3.la $GTS_LIBS $MODULES"
+
+
+
+
+# check whether the code is under darcs
+
+ if test -d _darcs; then
+  DARCS_CONTROLLED_TRUE=
+  DARCS_CONTROLLED_FALSE='#'
+else
+  DARCS_CONTROLLED_TRUE='#'
+  DARCS_CONTROLLED_FALSE=
+fi
+
+
+ac_config_files="$ac_config_files Makefile src/Makefile src/gfs-config src/gerris2D.pc src/gerris2D3.pc src/gerris3D.pc tools/Makefile modules/Makefile modules/wavewatch/Makefile test/Makefile doc/Makefile doc/tutorial/Makefile doc/examples/Makefile doc/manpages/Makefile doc/examples/gfs2doc doc/examples/gfs-highlight doc/examples/crossref.sh desktop/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_MODULES_TRUE}" && test -z "${HAVE_MODULES_FALSE}"; then
+  as_fn_error "conditional \"HAVE_MODULES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAS_LIBPROJ_TRUE}" && test -z "${HAS_LIBPROJ_FALSE}"; then
+  as_fn_error "conditional \"HAS_LIBPROJ\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAS_NETCDF_TRUE}" && test -z "${HAS_NETCDF_FALSE}"; then
+  as_fn_error "conditional \"HAS_NETCDF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_TIDE_TRUE}" && test -z "${BUILD_TIDE_FALSE}"; then
+  as_fn_error "conditional \"BUILD_TIDE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_STOKES_TRUE}" && test -z "${BUILD_STOKES_FALSE}"; then
+  as_fn_error "conditional \"BUILD_STOKES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_WAVEWATCH_TRUE}" && test -z "${BUILD_WAVEWATCH_FALSE}"; then
+  as_fn_error "conditional \"BUILD_WAVEWATCH\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${DARCS_CONTROLLED_TRUE}" && test -z "${DARCS_CONTROLLED_FALSE}"; then
+  as_fn_error "conditional \"DARCS_CONTROLLED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.64.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.64,
+  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+LD_F77='`$ECHO "X$LD_F77" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds_F77='`$ECHO "X$old_archive_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_F77='`$ECHO "X$compiler_F77" | $Xsed -e "$delay_single_quote_subst"`'
+GCC_F77='`$ECHO "X$GCC_F77" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_F77='`$ECHO "X$lt_prog_compiler_no_builtin_flag_F77" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_F77='`$ECHO "X$lt_prog_compiler_wl_F77" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_F77='`$ECHO "X$lt_prog_compiler_pic_F77" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static_F77='`$ECHO "X$lt_prog_compiler_static_F77" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_F77='`$ECHO "X$lt_cv_prog_compiler_c_o_F77" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc_F77='`$ECHO "X$archive_cmds_need_lc_F77" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_F77='`$ECHO "X$enable_shared_with_static_runtimes_F77" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_F77='`$ECHO "X$export_dynamic_flag_spec_F77" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec_F77='`$ECHO "X$whole_archive_flag_spec_F77" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object_F77='`$ECHO "X$compiler_needs_object_F77" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_F77='`$ECHO "X$old_archive_from_new_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_F77='`$ECHO "X$old_archive_from_expsyms_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_F77='`$ECHO "X$archive_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds_F77='`$ECHO "X$archive_expsym_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds_F77='`$ECHO "X$module_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds_F77='`$ECHO "X$module_expsym_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld_F77='`$ECHO "X$with_gnu_ld_F77" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag_F77='`$ECHO "X$allow_undefined_flag_F77" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag_F77='`$ECHO "X$no_undefined_flag_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_F77='`$ECHO "X$hardcode_libdir_flag_spec_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_F77='`$ECHO "X$hardcode_libdir_flag_spec_ld_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator_F77='`$ECHO "X$hardcode_libdir_separator_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_F77='`$ECHO "X$hardcode_direct_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute_F77='`$ECHO "X$hardcode_direct_absolute_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L_F77='`$ECHO "X$hardcode_minus_L_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_F77='`$ECHO "X$hardcode_shlibpath_var_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic_F77='`$ECHO "X$hardcode_automatic_F77" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath_F77='`$ECHO "X$inherit_rpath_F77" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs_F77='`$ECHO "X$link_all_deplibs_F77" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path_F77='`$ECHO "X$fix_srcfile_path_F77" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols_F77='`$ECHO "X$always_export_symbols_F77" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds_F77='`$ECHO "X$export_symbols_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms_F77='`$ECHO "X$exclude_expsyms_F77" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms_F77='`$ECHO "X$include_expsyms_F77" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds_F77='`$ECHO "X$prelink_cmds_F77" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec_F77='`$ECHO "X$file_list_spec_F77" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action_F77='`$ECHO "X$hardcode_action_F77" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib \
+LD_F77 \
+compiler_F77 \
+lt_prog_compiler_no_builtin_flag_F77 \
+lt_prog_compiler_wl_F77 \
+lt_prog_compiler_pic_F77 \
+lt_prog_compiler_static_F77 \
+lt_cv_prog_compiler_c_o_F77 \
+export_dynamic_flag_spec_F77 \
+whole_archive_flag_spec_F77 \
+compiler_needs_object_F77 \
+with_gnu_ld_F77 \
+allow_undefined_flag_F77 \
+no_undefined_flag_F77 \
+hardcode_libdir_flag_spec_F77 \
+hardcode_libdir_flag_spec_ld_F77 \
+hardcode_libdir_separator_F77 \
+fix_srcfile_path_F77 \
+exclude_expsyms_F77 \
+include_expsyms_F77 \
+file_list_spec_F77; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+old_archive_cmds_F77 \
+old_archive_from_new_cmds_F77 \
+old_archive_from_expsyms_cmds_F77 \
+archive_cmds_F77 \
+archive_expsym_cmds_F77 \
+module_cmds_F77 \
+module_expsym_cmds_F77 \
+export_symbols_cmds_F77 \
+prelink_cmds_F77; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"')  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+  ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+	build="$build"
+	have_gmodule="$have_gmodule"
+
+
+	have_gmodule="$have_gmodule"
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+    "default-2") CONFIG_COMMANDS="$CONFIG_COMMANDS default-2" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "src/gfs-config") CONFIG_FILES="$CONFIG_FILES src/gfs-config" ;;
+    "src/gerris2D.pc") CONFIG_FILES="$CONFIG_FILES src/gerris2D.pc" ;;
+    "src/gerris2D3.pc") CONFIG_FILES="$CONFIG_FILES src/gerris2D3.pc" ;;
+    "src/gerris3D.pc") CONFIG_FILES="$CONFIG_FILES src/gerris3D.pc" ;;
+    "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
+    "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;;
+    "modules/wavewatch/Makefile") CONFIG_FILES="$CONFIG_FILES modules/wavewatch/Makefile" ;;
+    "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+    "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+    "doc/tutorial/Makefile") CONFIG_FILES="$CONFIG_FILES doc/tutorial/Makefile" ;;
+    "doc/examples/Makefile") CONFIG_FILES="$CONFIG_FILES doc/examples/Makefile" ;;
+    "doc/manpages/Makefile") CONFIG_FILES="$CONFIG_FILES doc/manpages/Makefile" ;;
+    "doc/examples/gfs2doc") CONFIG_FILES="$CONFIG_FILES doc/examples/gfs2doc" ;;
+    "doc/examples/gfs-highlight") CONFIG_FILES="$CONFIG_FILES doc/examples/gfs-highlight" ;;
+    "doc/examples/crossref.sh") CONFIG_FILES="$CONFIG_FILES doc/examples/crossref.sh" ;;
+    "desktop/Makefile") CONFIG_FILES="$CONFIG_FILES desktop/Makefile" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="F77 "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Assembler program.
+AS=$AS
+
+# DLL creation program.
+DLLTOOL=$DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$OBJDUMP
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1+=\$2"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+    ;;
+  esac
+
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: F77
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_F77
+
+# A language specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_F77
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_F77
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_F77
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_F77
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_F77
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_F77
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_F77
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# ### END LIBTOOL TAG CONFIG: F77
+_LT_EOF
+
+ ;;
+    "default-1":C)
+	echo creating src/gfsconfig.h
+	cat >src/gfsconfig.h <<\__EOF
+/* gfsconfig.h
+ *
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+#ifndef GFSCONFIG_H
+#define GFSCONFIG_H
+
+__EOF
+	if test "$have_gmodule" = "yes"; then
+	  cat >> src/gfsconfig.h <<\__EOF
+#define GFS_HAS_MODULES 1
+
+__EOF
+	fi
+	case "$build" in
+	*-cray-unicos*)
+	  echo "/* CRAY inlining directives */" >> src/gfsconfig.h
+	  for file in src/*.h; do
+	  awk '
+BEGIN {
+  nc = 10;
+  nf = 0;
+}
+{
+  if ( == "G_INLINE_FUNC") {
+    nc = 0;
+    start = 2;
+  }
+  else
+    start = 1;
+  for (i = start; i <= NF; i++) {
+    if (nc == 1) {
+      if (substr ($i, 1, 1) != "*") {
+	in_list = 0;
+	for (j = 0; j < nf && !inlist; j++)
+	  if ($i == f[j])
+	    inlist = 1;
+	if (!inlist)
+          f[nf++] = $i;
+	nc = 10;
+      }
+    }
+    else
+      nc++;
+  }
+}
+END {
+  if (nf > 0) {
+    printf ("#pragma _CRI inline %s", f[0]);
+    for (i = 1; i < nf; i++)
+      printf (", %s", f[i]);
+    printf ("\n");
+  }
+}
+' < $file >> src/gfsconfig.h
+	done
+	;;
+	esac
+	cat >>src/gfsconfig.h <<__EOF
+
+#endif /* GFSCONFIG_H */
+__EOF
+ ;;
+    "default-2":C)
+	echo creating src/modules.c
+	cat > src/modules.c <<\__EOF
+/* modules.c
+ *
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+__EOF
+	cat > src/modules.h <<\__EOF
+/* modules.h
+ *
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+__EOF
+	if test "$have_gmodule" = "no"; then
+	  for file in `ls modules/*.mod`; do
+		name=`basename $file .mod`
+		echo "void gfs_init_$name (void);" >> src/modules.h
+		echo "gfs_init_$name ();" >> src/modules.c
+	  done
+	fi
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..2a22228
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,473 @@
+AC_INIT(configure.in)
+AC_CONFIG_MACRO_DIR([m4])
+
+dnl we to AC_DIVERT_PUSH/AC_DIVERT_POP these variable definitions so they
+dnl are available for $ac_help expansion (don't we all *love* autoconf?)
+#AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
+# Making releases:
+#   GFS_MICRO_VERSION += 1;
+#   GFS_INTERFACE_AGE += 1;
+#   GFS_BINARY_AGE += 1;
+# if any functions have been added, set GFS_INTERFACE_AGE to 0.
+# if backwards compatibility has been broken,
+# set GFS_BINARY_AGE and GFS_INTERFACE_AGE to 0.
+#
+# Remember to update rpm/gerris.spec when changing the version number.
+GFS_MAJOR_VERSION=1
+GFS_MINOR_VERSION=3
+GFS_MICRO_VERSION=2
+GFS_INTERFACE_AGE=0
+GFS_BINARY_AGE=0
+GFS_VERSION=$GFS_MAJOR_VERSION.$GFS_MINOR_VERSION.$GFS_MICRO_VERSION
+GFS_COMPILATION_FLAGS=$CFLAGS
+dnl
+#AC_DIVERT_POP()dnl
+
+AC_SUBST(GFS_MAJOR_VERSION)
+AC_SUBST(GFS_MINOR_VERSION)
+AC_SUBST(GFS_MICRO_VERSION)
+AC_SUBST(GFS_VERSION)
+AC_SUBST(GFS_COMPILATION_FLAGS)
+
+# libtool versioning
+LT_RELEASE=$GFS_MAJOR_VERSION.$GFS_MINOR_VERSION
+LT_CURRENT=`expr $GFS_MICRO_VERSION - $GFS_INTERFACE_AGE`
+LT_REVISION=$GFS_INTERFACE_AGE
+LT_AGE=`expr $GFS_BINARY_AGE - $GFS_INTERFACE_AGE`
+AC_SUBST(LT_RELEASE)
+AC_SUBST(LT_CURRENT)
+AC_SUBST(LT_REVISION)
+AC_SUBST(LT_AGE)
+
+# For automake.
+VERSION=$GFS_VERSION
+PACKAGE=gerris
+
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
+
+# Specify a configuration file
+AM_CONFIG_HEADER(config.h)
+
+AC_DEFINE_UNQUOTED(GFS_MAJOR_VERSION, $GFS_MAJOR_VERSION, [Major version])
+AC_DEFINE_UNQUOTED(GFS_MINOR_VERSION, $GFS_MINOR_VERSION, [Minor version])
+AC_DEFINE_UNQUOTED(GFS_MICRO_VERSION, $GFS_MICRO_VERSION, [Micro version])
+AC_DEFINE_UNQUOTED(GFS_INTERFACE_AGE, $GFS_INTERFACE_AGE, [Interface age])
+AC_DEFINE_UNQUOTED(GFS_BINARY_AGE, $GFS_BINARY_AGE,       [Binary age])
+AC_DEFINE_UNQUOTED(GFS_VERSION, "$GFS_VERSION",           [Version])
+AC_DEFINE_UNQUOTED(GFS_COMPILATION_FLAGS, "$GFS_COMPILATION_FLAGS", [Compilation flags])
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_ARG_WITH(mpicc,
+              [  --with-mpicc=path       pick a specific path to mpicc],
+              [with_mpicc=$withval],
+              [with_mpicc=''])
+
+# check if MPI support is disabled
+AC_ARG_ENABLE(mpi,
+[  --disable-mpi           do not compile MPI support],
+[ case "${enableval}" in
+	yes) ;;
+	*) with_mpicc=no ;;
+  esac])
+
+if test "x$with_mpicc" != "xno" ; then
+  if test "x$with_mpicc" != "x" ; then
+     if test -x "$with_mpicc" ; then
+       use_mpicc=yes
+       CC="$with_mpicc"
+     fi
+  else
+     AC_CHECK_PROG(use_mpicc, mpicc, yes)
+     if test "x$use_mpicc" = "xyes" ; then
+       CC=mpicc
+     fi
+  fi
+  if test "x$use_mpicc" = "xyes" ; then
+     AC_DEFINE(HAVE_MPI, 1, [Define to 1 if you have MPI])
+  else
+     AC_MSG_WARN([MPI not found. No MPI support will be compiled in.])
+  fi
+fi
+
+AC_PROG_CC
+
+if test x$GCC = xyes ; then
+  CFLAGS="$CFLAGS -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -Wmissing-declarations -pipe"
+fi
+
+dnl Initialize libtool
+AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
+
+dnl Enable verbose output from libtool (enable libtool's default)
+AC_ARG_ENABLE(libtool-verbose,
+	      [  --enable-libtool-verbose enable verbose libtool output (default disabled)],
+	      [with_libtool_verbose=$enableval],
+	      [with_libtool_verbose='no'])
+if test "$with_libtool_verbose" = 'no'
+then
+  LIBTOOL="$LIBTOOL --silent"
+fi
+
+dnl Fix for MacOSX and cygwin libtool
+case "$build" in
+  *-apple-darwin*) NO_UNDEFINED="" ;;
+  *-pc-cygwin*)    NO_UNDEFINED="" ;;
+  *)               NO_UNDEFINED="-no-undefined" ;;
+esac
+AC_SUBST(NO_UNDEFINED)
+
+AC_PROG_AWK
+AC_ISC_POSIX
+AC_HEADER_STDC
+
+# check that pointers can be stored in doubles
+AC_MSG_CHECKING(whether pointers can be stored in doubles)
+AC_TRY_RUN([
+main () {
+  if (sizeof (void *) > sizeof (double))
+    return 1;
+  return 0;
+}
+], can_store_pointers=yes, can_store_pointers=no,
+[can_store_pointers=yes; echo $ac_n "cross compiling; assumed OK... $ac_c"])
+AC_MSG_RESULT($can_store_pointers)
+if test x$can_store_pointers = xno ; then
+  AC_MSG_ERROR([
+*** Pointers cannot be stored in doubles on this architecture.])
+fi
+
+# check if we want to enable GTS casts checks
+AC_ARG_ENABLE(gts-check,
+[  --enable-gts-check      enable object type cast checks in GTS],
+[ case "${enableval}" in
+	*) gts_check_casts="--check" ;;
+  esac])
+
+if test x$with_gts = xyes ; then
+  AC_MSG_ERROR([
+*** Directory must be specified for --with-gts])
+fi
+
+if test x$with_gts = x ; then 
+  # Look for separately installed gts
+
+  AM_PATH_GTS(0.7.4,,
+    AC_MSG_ERROR([
+*** GTS 0.7.4 or better is required. The latest version of GTS
+*** is always available from http://gts.sourceforge.net.]))
+
+  gts_cflags=`$GTS_CONFIG --cflags $gts_check_casts gmodule`
+  gts_libs=`$GTS_CONFIG --libs gmodule`
+  GTS_LIBS="$gts_libs"
+  GTS_DEPLIBS="$gts_libs"
+else
+  # Use uninstalled gts (assume they got the version right)
+
+  GTS_CONFIG=$with_gts/gts-config
+  if test -x $GTS_CONFIG ; then 
+    :
+  else
+    AC_MSG_ERROR([GTS directory ($with_gts) not present or not configured])
+  fi
+
+  # For use in gfs-config
+  gts_cflags=`$GTS_CONFIG --cflags $gts_check_casts gmodule`
+  gts_libs=`$GTS_CONFIG --libs gmodule`
+  gts_release=`$GTS_CONFIG --version | sed 's%\\.[[0-9]]*$%%'`
+
+  # canonicalize relative paths
+  case $with_gts in 
+    /*)
+      gts_dir=$with_gts
+      ;;
+    *)
+      gts_dir="\$(top_builddir)/$with_gts"
+      ;;
+  esac
+
+  GTS_CFLAGS="-I$gts_dir"
+  if test -n "$gts_check_casts"; then
+	 GTS_CFLAGS="$GTS_CFLAGS -DGTS_CHECK_CASTS"
+  fi
+  GTS_LIBS="$gts_dir/libgts.la"
+  GTS_DEPLIBS=
+
+  AC_SUBST(GTS_LIBS)
+fi
+
+if test -n "$gts_check_casts"; then
+  GTS_CFLAGS="$GTS_CFLAGS -DGTS_CHECK_CASTS"
+fi
+AC_SUBST(GTS_CFLAGS)
+AC_SUBST(gts_cflags)
+AC_SUBST(gts_libs)
+AC_SUBST(GTS_DEPLIBS)
+
+# check whether GModules are supported
+AC_MSG_CHECKING(whether modules are supported)
+OLD_CFLAGS=$CFLAGS
+CFLAGS=$gts_cflags
+OLD_LIBS=$LIBS
+LIBS=$gts_libs
+AC_TRY_RUN([
+#include <glib.h>
+#include <gmodule.h>
+
+main () {
+  if (!g_module_supported ())
+    return 1;
+  return 0;
+}
+], have_gmodule=yes, have_gmodule=no,
+[have_gmodule=yes; echo $ac_n "cross compiling; assumed OK... $ac_c"])
+AC_MSG_RESULT($have_gmodule)
+CFLAGS=$OLD_CFLAGS
+LIBS=$OLD_LIBS
+
+# checking how to build modules
+if test "$have_gmodule" = "yes"; then
+   module_flags=""
+   for flags in \
+       "-fPIC -shared -x c" \
+       "-fPIC -dynamiclib -x c -undefined dynamic_lookup" \
+       "-fPIC -bundle -x c"
+   do
+	if test x"$module_flags" = x; then
+	   if echo "test(){}" | gcc $flags - 2> /dev/null; then
+	      module_flags=\"$flags\"
+	   fi
+	fi
+   done
+   if test x"$module_flags" = x; then
+	have_gmodule=no
+	AC_MSG_WARN([Could not build module, functions in parameter files will not be supported.])
+   fi
+   AC_DEFINE_UNQUOTED(MODULES_FLAGS, $module_flags, [Linking flags to build modules.])
+fi
+
+# checks for pkg-config
+if test "$have_gmodule" = "yes"; then
+  AC_CHECK_PROG(have_pkg_config, pkg-config, yes, no)
+  if test "$have_pkg_config" = "no"; then
+    AC_MSG_WARN([pkg-config is required for functions in parameter files.])
+  fi
+fi
+if test x"$have_pkg_config" = x"yes"; then
+  AC_DEFINE(HAVE_PKG_CONFIG, 1, [Define to 1 if GModule are supported and if you have pkg-config.])
+else
+  AC_DEFINE(HAVE_PKG_CONFIG, 0)
+fi
+
+# checks for gawk and m4
+AC_CHECK_PROG(have_awk, gawk, yes, no)
+if test "$have_awk" = "yes"; then
+   AC_CHECK_PROG(have_m4, m4, yes, no)
+   if test "$have_m4" = "yes"; then
+      AC_DEFINE(HAVE_M4, 1, [Define to 1 if gawk and m4 are available.])
+   else
+      AC_DEFINE(HAVE_M4, 0)
+   fi
+fi
+
+# check if module support is disabled
+AC_ARG_ENABLE(modules,
+[  --disable-modules       link modules statically with the executables],
+[ case "${enableval}" in
+	yes) ;;
+	*) have_gmodule=no ;;
+  esac])
+
+AC_SUBST(have_gmodule)
+AM_CONDITIONAL(HAVE_MODULES, test "$have_gmodule" = "yes")
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+# checks for libproj
+AC_CHECK_LIB(proj, pj_fwd, proj="true",
+  AC_MSG_WARN([libproj not found. Map module will not be available.]), [-lm])
+AC_CHECK_HEADERS(proj_api.h, proj="true", proj="false")
+AM_CONDITIONAL(HAS_LIBPROJ, test x$proj = xtrue)
+
+# checks for GNU Scientific Library
+AM_PATH_GSL
+
+# checks for netCDF
+AC_CHECK_LIB(netcdf, nc_open, netcdf="true", netcdf="false", [-lm])
+AC_CHECK_HEADERS(netcdf.h, netcdf="true", netcdf="false")
+AM_CONDITIONAL(HAS_NETCDF, test x$netcdf = xtrue)
+
+# Tide module requires both netCDF and GSL
+if test x$netcdf = xfalse -o x$no_gsl = xyes; then
+   AC_MSG_WARN([GSL and/or netCDF not found. Tide module will not be available.])
+fi
+AM_CONDITIONAL(BUILD_TIDE, test x$netcdf = xtrue -a x$no_gsl = x)
+
+# Stokes module requires a fortran compiler
+AC_PROG_F77
+AM_CONDITIONAL(BUILD_STOKES, test x$F77 != x)
+
+# Build wavewatch module if wavewatch is installed
+AM_CONDITIONAL(BUILD_WAVEWATCH, test -r $HOME/.wwatch3.env)
+if test -r $HOME/.wwatch3.env; then
+   ww3_dir=`grep WWATCH3_DIR $HOME/.wwatch3.env | awk '{print $2}'`
+   ww3_version=`grep "WWVER  = " $ww3_dir/ftn/*.ftn | \
+                awk '{print substr($(NF-1),2)}' | \
+                sed 's/\.//'`
+   W3INIT="w3init$ww3_version"
+   AC_SUBST(W3INIT)
+   AC_DEFINE_UNQUOTED(WW3_VERSION, $ww3_version, [WaveWatch III version number])
+fi
+
+dnl header file checks
+AC_CHECK_HEADERS(fenv.h, AC_DEFINE(HAVE_FENV_H))
+AC_CHECK_HEADERS(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
+AC_CHECK_HEADERS(getopt.h, AC_DEFINE(HAVE_GETOPT_H))
+
+dnl functions checks
+AC_CHECK_FUNCS(getopt_long)
+
+dnl generate `src/gfsconfig.h'
+AC_OUTPUT_COMMANDS([
+	echo creating src/gfsconfig.h
+	cat >src/gfsconfig.h <<\__EOF
+/* gfsconfig.h
+ * 
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+#ifndef GFSCONFIG_H
+#define GFSCONFIG_H
+
+__EOF
+	if test "$have_gmodule" = "yes"; then
+	  cat >> src/gfsconfig.h <<\__EOF
+#define GFS_HAS_MODULES 1
+
+__EOF
+	fi
+	case "$build" in
+	*-cray-unicos*)
+	  echo "/* CRAY inlining directives */" >> src/gfsconfig.h
+	  for file in src/*.h; do
+	  awk '
+BEGIN {
+  nc = 10;
+  nf = 0;
+}
+{
+  if ($1 == "G_INLINE_FUNC") {
+    nc = 0;
+    start = 2;
+  }
+  else
+    start = 1;
+  for (i = start; i <= NF; i++) {
+    if (nc == 1) {
+      if (substr ($i, 1, 1) != "*") {
+	in_list = 0;
+	for (j = 0; j < nf && !inlist; j++)
+	  if ($i == f[j])
+	    inlist = 1;
+	if (!inlist)
+          f[nf++] = $i;
+	nc = 10;
+      }
+    }
+    else
+      nc++;
+  }
+}
+END {
+  if (nf > 0) {
+    printf ("#pragma _CRI inline %s", f[0]);
+    for (i = 1; i < nf; i++)
+      printf (", %s", f[i]);
+    printf ("\n");
+  }
+}
+' < $file >> src/gfsconfig.h
+	done
+	;;
+	esac
+	cat >>src/gfsconfig.h <<__EOF
+
+#endif /* GFSCONFIG_H */
+__EOF
+],[
+	build="$build"
+	have_gmodule="$have_gmodule"
+])
+
+dnl generate `src/modules.c'
+AC_OUTPUT_COMMANDS([
+	echo creating src/modules.c
+	cat > src/modules.c <<\__EOF
+/* modules.c
+ * 
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+__EOF
+	cat > src/modules.h <<\__EOF
+/* modules.h
+ * 
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+__EOF
+	if test "$have_gmodule" = "no"; then
+	  for file in `ls modules/*.mod`; do
+		name=`basename $file .mod`
+		echo "void gfs_init_$name (void);" >> src/modules.h
+		echo "gfs_init_$name ();" >> src/modules.c
+	  done
+	fi
+],[
+	have_gmodule="$have_gmodule"
+])
+
+dnl export MODULES for src/Makefile.am
+MODULES=""
+if test "$have_gmodule" = "no"; then
+  for file in `ls modules/*.mod`; do
+	name=`basename $file .mod`
+	MODULES=" $MODULES ../modules/$name.o"
+  done	
+fi
+AC_SUBST(MODULES)
+GFS2D_LIBS="\$(top_builddir)/src/libgfs2D.la $GTS_LIBS $MODULES"
+GFS3D_LIBS="\$(top_builddir)/src/libgfs3D.la $GTS_LIBS $MODULES"
+GFS2D3_LIBS="\$(top_builddir)/src/libgfs2D3.la $GTS_LIBS $MODULES"
+AC_SUBST(GFS2D_LIBS)
+AC_SUBST(GFS3D_LIBS)
+AC_SUBST(GFS2D3_LIBS)
+
+# check whether the code is under darcs
+
+AM_CONDITIONAL(DARCS_CONTROLLED, test -d _darcs)
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+src/gfs-config
+src/gerris2D.pc
+src/gerris2D3.pc
+src/gerris3D.pc
+tools/Makefile
+modules/Makefile
+modules/wavewatch/Makefile
+test/Makefile
+doc/Makefile
+doc/tutorial/Makefile
+doc/examples/Makefile
+doc/manpages/Makefile
+doc/examples/gfs2doc
+doc/examples/gfs-highlight
+doc/examples/crossref.sh
+desktop/Makefile
+])
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..25bdb18
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,526 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2004-04-25.13
+
+# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+# 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 2, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit 0
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+   dir=`echo "$object" | sed 's,/.*$,/,'`
+   if test "$dir" = "$object"; then
+      dir=
+   fi
+   # FIXME: should be _deps on DOS.
+   depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # Dependencies are output in .lo.d with libtool 1.4.
+      # They are output in .o.d with libtool 1.5.
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir.libs/$base.o.d"
+      tmpdepfile3="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      tmpdepfile3="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   elif test -f "$tmpdepfile2"; then
+      tmpdepfile="$tmpdepfile2"
+   else
+      tmpdepfile="$tmpdepfile3"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/desktop/Makefile.am b/desktop/Makefile.am
new file mode 100644
index 0000000..97ba870
--- /dev/null
+++ b/desktop/Makefile.am
@@ -0,0 +1,15 @@
+## Process this file with automake to produce Makefile.in
+
+mimedir = $(datadir)/mime/packages
+mime_DATA = gerris.xml
+
+iconsdir = $(datadir)/icons/hicolor/48x48/mimetypes
+
+ICONS = application-gerris.png \
+	application-gerris-2D.png \
+	application-gerris-3D.png \
+	application-gerris-compressed.png
+
+icons_DATA = $(ICONS)
+
+EXTRA_DIST = gerris.xml $(ICONS)
diff --git a/desktop/Makefile.in b/desktop/Makefile.in
new file mode 100644
index 0000000..8d2ada8
--- /dev/null
+++ b/desktop/Makefile.in
@@ -0,0 +1,462 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = desktop
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(iconsdir)" "$(DESTDIR)$(mimedir)"
+DATA = $(icons_DATA) $(mime_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+mimedir = $(datadir)/mime/packages
+mime_DATA = gerris.xml
+iconsdir = $(datadir)/icons/hicolor/48x48/mimetypes
+ICONS = application-gerris.png \
+	application-gerris-2D.png \
+	application-gerris-3D.png \
+	application-gerris-compressed.png
+
+icons_DATA = $(ICONS)
+EXTRA_DIST = gerris.xml $(ICONS)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu desktop/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu desktop/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-iconsDATA: $(icons_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(iconsdir)" || $(MKDIR_P) "$(DESTDIR)$(iconsdir)"
+	@list='$(icons_DATA)'; test -n "$(iconsdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(iconsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(iconsdir)" || exit $$?; \
+	done
+
+uninstall-iconsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(icons_DATA)'; test -n "$(iconsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(iconsdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(iconsdir)" && rm -f $$files
+install-mimeDATA: $(mime_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(mimedir)" || $(MKDIR_P) "$(DESTDIR)$(mimedir)"
+	@list='$(mime_DATA)'; test -n "$(mimedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(mimedir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(mimedir)" || exit $$?; \
+	done
+
+uninstall-mimeDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(mime_DATA)'; test -n "$(mimedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(mimedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(mimedir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(iconsdir)" "$(DESTDIR)$(mimedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-iconsDATA install-mimeDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-iconsDATA uninstall-mimeDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-iconsDATA install-info install-info-am install-man \
+	install-mimeDATA install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am uninstall uninstall-am uninstall-iconsDATA \
+	uninstall-mimeDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/desktop/application-gerris-2D.png b/desktop/application-gerris-2D.png
new file mode 100644
index 0000000..f718742
Binary files /dev/null and b/desktop/application-gerris-2D.png differ
diff --git a/desktop/application-gerris-3D.png b/desktop/application-gerris-3D.png
new file mode 100644
index 0000000..6950e1b
Binary files /dev/null and b/desktop/application-gerris-3D.png differ
diff --git a/desktop/application-gerris-compressed.png b/desktop/application-gerris-compressed.png
new file mode 100644
index 0000000..e3ecb70
Binary files /dev/null and b/desktop/application-gerris-compressed.png differ
diff --git a/desktop/application-gerris.png b/desktop/application-gerris.png
new file mode 100644
index 0000000..43fc662
Binary files /dev/null and b/desktop/application-gerris.png differ
diff --git a/desktop/gerris.xml b/desktop/gerris.xml
new file mode 100644
index 0000000..6fa0bf9
--- /dev/null
+++ b/desktop/gerris.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+  <mime-type type="application/gerris">
+    <sub-class-of type="text/plain"/>
+    <comment xml:lang="en">Gerris simulation</comment>
+    <glob pattern="*.gfs"/>
+  </mime-type>
+  <mime-type type="application/gerris-compressed">
+    <sub-class-of type="application/x-gzip"/>
+    <comment xml:lang="en">Gerris simulation</comment>
+    <glob pattern="*.gfs.gz"/>
+  </mime-type>
+  <mime-type type="application/gerris-2D">
+    <sub-class-of type="application/gerris"/>
+    <comment xml:lang="en">Gerris 2D simulation</comment>
+    <magic priority="80">
+      <match type="string" value="# Gerris Flow Solver 2D " offset="0"/>
+    </magic>
+  </mime-type>
+  <mime-type type="application/gerris-3D">
+    <sub-class-of type="application/gerris"/>
+    <comment xml:lang="en">Gerris 3D simulation</comment>
+    <magic priority="80">
+      <match type="string" value="# Gerris Flow Solver 3D " offset="0"/>
+    </magic>
+  </mime-type>
+</mime-info>
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..60c58c8
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,45 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = tutorial examples manpages
+
+# The name of the module.
+DOC_MODULE=gfs
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE=gfs-docs.sgml
+
+# The directory containing the source code (if it contains documentation).
+DOC_SOURCE_DIR=../src
+
+TARGET_DIR=html/$(DOC_MODULE)
+
+EXTRA_DIST=figures share
+
+scan:
+	gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers=""
+
+templates: scan
+	gtkdoc-mktmpl --module=$(DOC_MODULE)
+	sort -f $(DOC_MODULE)-unused.txt > /tmp/toto; mv -f /tmp/toto $(DOC_MODULE)-unused.txt
+
+sgml: templates
+	gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR)
+	sort -f $(DOC_MODULE)-undocumented.txt > /tmp/toto; mv -f /tmp/toto $(DOC_MODULE)-undocumented.txt
+
+html: sgml
+	if ! test -d html ; then mkdir html ; fi
+	-cd html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+
+clean-local:
+	rm -f *~ *.bak *.hierarchy *.signals *.args *-unused.txt
+
+maintainer-clean-local: clean
+	rm -rf sgml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt 
+
+## install-data-local:
+##	install -d -m 0755 $(TARGET_DIR)
+##	install -m 0644 html/*.html $(TARGET_DIR)
+##	install -m 0644 html/index.sgml $(TARGET_DIR)
+##	gtkdoc-fixxref --module=$(DOC_MODULE) --html-dir=$(HTML_DIR)
+
+.PHONY : html sgml templates scan
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..cf69c74
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,619 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+SUBDIRS = tutorial examples manpages
+
+# The name of the module.
+DOC_MODULE = gfs
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE = gfs-docs.sgml
+
+# The directory containing the source code (if it contains documentation).
+DOC_SOURCE_DIR = ../src
+TARGET_DIR = html/$(DOC_MODULE)
+EXTRA_DIST = figures share
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+	maintainer-clean-local
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-generic clean-libtool \
+	clean-local ctags ctags-recursive distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic maintainer-clean-local mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am
+
+
+scan:
+	gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers=""
+
+templates: scan
+	gtkdoc-mktmpl --module=$(DOC_MODULE)
+	sort -f $(DOC_MODULE)-unused.txt > /tmp/toto; mv -f /tmp/toto $(DOC_MODULE)-unused.txt
+
+sgml: templates
+	gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR)
+	sort -f $(DOC_MODULE)-undocumented.txt > /tmp/toto; mv -f /tmp/toto $(DOC_MODULE)-undocumented.txt
+
+html: sgml
+	if ! test -d html ; then mkdir html ; fi
+	-cd html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+
+clean-local:
+	rm -f *~ *.bak *.hierarchy *.signals *.args *-unused.txt
+
+maintainer-clean-local: clean
+	rm -rf sgml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt 
+
+.PHONY : html sgml templates scan
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
new file mode 100644
index 0000000..d891767
--- /dev/null
+++ b/doc/examples/Makefile.am
@@ -0,0 +1,104 @@
+## Process this file with automake to produce Makefile.in
+
+EXAMPLES = \
+	cylinder \
+	rt \
+	boussinesq \
+	tangaroa \
+	logo \
+	tides \
+	ship \
+	garden \
+	dam \
+	hump
+
+EXTRA_DIST = \
+	template.tex \
+	gfs2tex.py \
+	gfs2tex \
+	depend.py \
+	test.py \
+	Makefile.deps \
+	crossref.sh.in \
+	gfsxref
+
+TESTS = test.sh
+
+test.sh: $(EXAMPLES)
+	@echo "python test.py $(EXAMPLES)" > test.sh
+	@chmod +x test.sh
+
+bin_SCRIPTS = \
+	gfs2doc gfs-highlight gfsxref
+
+BUILT_SOURCES= \
+	gfs2doc gfs-highlight gfs.lang gerris.dic
+
+CLEANFILES = $(BUILT_SOURCES) Makefile.deps
+
+pkglib_DATA = gfs2tex.py
+pkgdata_DATA = gfs.lang gerris.dic
+
+gfs.lang: classes
+	$(srcdir)/classes > gfs.lang
+
+gerris.dic: classes
+	$(srcdir)/classes | awk '$$1 ~ /gfs_keyword/ {print $$3}' | sed 's/"//g' > gerris.dic
+
+gfs2doc: gfs2doc.in
+
+gfs-highlight: gfs-highlight.in
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out examples.tex *.pyc test.sh gfs2doc
+	$(RM) -r examples
+
+DOC = examples
+
+examples: examples.dvi crossref.sh
+	hevea -fix $(DOC).tex
+	imagen -res 600 -extra "pnmscale 0.24" $(DOC)
+	hacha $(DOC).html
+	rm -f $(DOC).html
+	mv -f $(DOC)[0-9][0-9][0-9].png $(DOC)
+##	fixme: the character conversion below is a workaround for a bug in hevea version < 1.09
+##	for f in *.html; do konwert iso1-utf8 < $$f > $(DOC)/$$f; rm -f $$f; done
+	mv -f *.html $(DOC)
+	cat $(DOC).css ../share/darcs.css > $(DOC)/$(DOC).css
+	sh ../share/fixnav.sh $(DOC)
+	cp -f ../share/contents.png ../share/next.png ../share/prev.png $(DOC)
+	rm -f *_motif.gif $(DOC).h{tml,aux,ind,toc} $(DOC).image.tex $(DOC).css
+	sh ./crossref.sh --url=http://gfs.sourceforge.net/examples/examples $(EXAMPLES)
+	mv references examples
+
+examples.dvi: examples.tex
+	latex -interaction=nonstopmode examples.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode examples.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode examples.tex
+
+examples.pdf: examples.dvi
+	dvips -Ppdf -G0 examples.dvi -o examples.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true examples.ps examples.pdf
+	rm -f examples.ps
+
+examples.tex: template.tex Makefile.deps gfs2tex gfs2tex.py
+	rm -r -f examples
+	python gfs2tex $(EXAMPLES)
+	sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" < template.tex | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > examples.tex
+
+Makefile.deps: Makefile depend.py
+	python depend.py $(EXAMPLES) > Makefile.deps
+
+-include Makefile.deps
+
+examples.tar.gz: examples.pdf examples $(DOCS)
+	tar czf examples.tar.gz examples $(DOCS)
+
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) -DG_LOG_DOMAIN=\"Gfs-tools\"\
+            $(GTS_CFLAGS)
+
+noinst_PROGRAMS = classes
+
+classes: classes.c $(top_srcdir)/src/init.c
+	$(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(INCLUDES) -DFTT_2D=1 \
+	classes.c -o classes $(GFS2D_LIBS)
diff --git a/doc/examples/Makefile.deps b/doc/examples/Makefile.deps
new file mode 100644
index 0000000..913b020
--- /dev/null
+++ b/doc/examples/Makefile.deps
@@ -0,0 +1,116 @@
+DOCS = \
+	cylinder/cylinder.gfs.html\
+	cylinder/t.mpg\
+	cylinder/vort.mpg\
+	cylinder/heated/heated.gfs.html\
+	cylinder/heated/t.mpg\
+	cylinder/parallel/parallel.gfs.html\
+	cylinder/parallel/pid.mpg\
+	rt/rt.gfs.html\
+	rt/t.mpg\
+	rt/vort.mpg\
+	boussinesq/boussinesq.gfs.html\
+	boussinesq/t.mpg\
+	tangaroa/tangaroa.gfs.html\
+	tangaroa/sections.mpg\
+	logo/logo.gfs.html\
+	logo/logo.mpg\
+	tides/tides.gfs.html\
+	ship/ship.gfs.html\
+	ship/closeup.mpg\
+	garden/garden.gfs.html\
+	dam/dam.gfs.html\
+	hump/hump.gfs.html\
+	hump/hump.mpg\
+	cylinder/cylinder.gfs\
+	cylinder/heated/heated.gfs\
+	cylinder/parallel/parallel.gfs\
+	rt/rt.gfs\
+	boussinesq/boussinesq.gfs\
+	tangaroa/tangaroa.gfs\
+	logo/logo.gfs\
+	tides/tides.gfs\
+	ship/ship.gfs\
+	garden/garden.gfs\
+	dam/dam.gfs\
+	hump/hump.gfs
+
+EXTRA_DIST += \
+	cylinder/cylinder.gfs\
+	cylinder/heated/heated.gfs\
+	cylinder/parallel/parallel.gfs\
+	rt/rt.gfs\
+	boussinesq/boussinesq.gfs\
+	tangaroa/tangaroa.gfs\
+	logo/logo.gfs\
+	tides/tides.gfs\
+	ship/ship.gfs\
+	garden/garden.gfs\
+	dam/dam.gfs\
+	hump/hump.gfs
+
+examples.tex: \
+	cylinder/cylinder.gfs\
+	cylinder/t.mpg\
+	cylinder/vort.mpg\
+	cylinder/t.eps\
+	cylinder/vort.eps\
+	cylinder/heated/heated.gfs\
+	cylinder/heated/t.mpg\
+	cylinder/heated/t.eps\
+	cylinder/parallel/parallel.gfs\
+	cylinder/parallel/pid.mpg\
+	cylinder/parallel/pid.eps\
+	cylinder/parallel/balance.eps\
+	rt/rt.gfs\
+	rt/t.mpg\
+	rt/vort.mpg\
+	rt/t.eps\
+	rt/vort.eps\
+	rt/t-0.eps\
+	rt/t-0.7.eps\
+	rt/t-0.8.eps\
+	rt/t-0.9.eps\
+	rt/t-1.eps\
+	boussinesq/boussinesq.gfs\
+	boussinesq/t.mpg\
+	boussinesq/t.eps\
+	tangaroa/tangaroa.gfs\
+	tangaroa/sections.mpg\
+	tangaroa/sections.eps\
+	logo/logo.gfs\
+	logo/logo.mpg\
+	logo/logo.png\
+	logo/logo.eps\
+	tides/tides.gfs\
+	tides/a0.eps\
+	tides/amplitude.eps\
+	tides/ellipses.eps\
+	tides/phase.eps\
+	tides/pv.eps\
+	tides/residual.eps\
+	ship/ship.gfs\
+	ship/closeup.mpg\
+	ship/closeup.eps\
+	ship/front.eps\
+	ship/f.eps\
+	ship/comparison.eps\
+	garden/garden.gfs\
+	garden/end.eps\
+	garden/mesh.eps\
+	garden/cpu.tex\
+	dam/dam.gfs\
+	dam/dam.gif\
+	hump/hump.gfs\
+	hump/cells-0.6.eps\
+	hump/cells-1.2.eps\
+	hump/cells-1.8.eps\
+	hump/iso-0.9.eps\
+	hump/iso-1.5.eps\
+	hump/cells-0.9.eps\
+	hump/cells-1.5.eps\
+	hump/iso-0.6.eps\
+	hump/iso-1.2.eps\
+	hump/iso-1.8.eps\
+	hump/hump.eps\
+	hump/hump.mpg
diff --git a/doc/examples/Makefile.in b/doc/examples/Makefile.in
new file mode 100644
index 0000000..5d93d85
--- /dev/null
+++ b/doc/examples/Makefile.in
@@ -0,0 +1,804 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = classes$(EXEEXT)
+subdir = doc/examples
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(srcdir)/crossref.sh.in $(srcdir)/gfs-highlight.in \
+	$(srcdir)/gfs2doc.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gfs2doc gfs-highlight crossref.sh
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+classes_SOURCES = classes.c
+classes_OBJECTS = classes.$(OBJEXT)
+classes_LDADD = $(LDADD)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" \
+	"$(DESTDIR)$(pkglibdir)"
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = classes.c
+DIST_SOURCES = classes.c
+DATA = $(pkgdata_DATA) $(pkglib_DATA)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+EXAMPLES = \
+	cylinder \
+	rt \
+	boussinesq \
+	tangaroa \
+	logo \
+	tides \
+	ship \
+	garden \
+	dam \
+	hump
+
+EXTRA_DIST = \
+	template.tex \
+	gfs2tex.py \
+	gfs2tex \
+	depend.py \
+	test.py \
+	Makefile.deps \
+	crossref.sh.in \
+	gfsxref
+
+TESTS = test.sh
+bin_SCRIPTS = \
+	gfs2doc gfs-highlight gfsxref
+
+BUILT_SOURCES = \
+	gfs2doc gfs-highlight gfs.lang gerris.dic
+
+CLEANFILES = $(BUILT_SOURCES) Makefile.deps
+pkglib_DATA = gfs2tex.py
+pkgdata_DATA = gfs.lang gerris.dic
+DOC = examples
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) -DG_LOG_DOMAIN=\"Gfs-tools\"\
+            $(GTS_CFLAGS)
+
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/examples/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu doc/examples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+gfs2doc: $(top_builddir)/config.status $(srcdir)/gfs2doc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+gfs-highlight: $(top_builddir)/config.status $(srcdir)/gfs-highlight.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+crossref.sh: $(top_builddir)/config.status $(srcdir)/crossref.sh.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/classes.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-pkgdataDATA: $(pkgdata_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)"
+	@list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \
+	done
+
+uninstall-pkgdataDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files
+install-pkglibDATA: $(pkglib_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkglibdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkglibdir)" || exit $$?; \
+	done
+
+uninstall-pkglibDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    echo "$$grn$$dashes"; \
+	  else \
+	    echo "$$red$$dashes"; \
+	  fi; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes$$std"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkglibdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgdataDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS install-pkglibDATA
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-pkgdataDATA \
+	uninstall-pkglibDATA
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+	clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binSCRIPTS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-pkgdataDATA install-pkglibDATA \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-binSCRIPTS \
+	uninstall-pkgdataDATA uninstall-pkglibDATA
+
+
+test.sh: $(EXAMPLES)
+	@echo "python test.py $(EXAMPLES)" > test.sh
+	@chmod +x test.sh
+
+gfs.lang: classes
+	$(srcdir)/classes > gfs.lang
+
+gerris.dic: classes
+	$(srcdir)/classes | awk '$$1 ~ /gfs_keyword/ {print $$3}' | sed 's/"//g' > gerris.dic
+
+gfs2doc: gfs2doc.in
+
+gfs-highlight: gfs-highlight.in
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out examples.tex *.pyc test.sh gfs2doc
+	$(RM) -r examples
+
+examples: examples.dvi crossref.sh
+	hevea -fix $(DOC).tex
+	imagen -res 600 -extra "pnmscale 0.24" $(DOC)
+	hacha $(DOC).html
+	rm -f $(DOC).html
+	mv -f $(DOC)[0-9][0-9][0-9].png $(DOC)
+	mv -f *.html $(DOC)
+	cat $(DOC).css ../share/darcs.css > $(DOC)/$(DOC).css
+	sh ../share/fixnav.sh $(DOC)
+	cp -f ../share/contents.png ../share/next.png ../share/prev.png $(DOC)
+	rm -f *_motif.gif $(DOC).h{tml,aux,ind,toc} $(DOC).image.tex $(DOC).css
+	sh ./crossref.sh --url=http://gfs.sourceforge.net/examples/examples $(EXAMPLES)
+	mv references examples
+
+examples.dvi: examples.tex
+	latex -interaction=nonstopmode examples.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode examples.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode examples.tex
+
+examples.pdf: examples.dvi
+	dvips -Ppdf -G0 examples.dvi -o examples.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true examples.ps examples.pdf
+	rm -f examples.ps
+
+examples.tex: template.tex Makefile.deps gfs2tex gfs2tex.py
+	rm -r -f examples
+	python gfs2tex $(EXAMPLES)
+	sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" < template.tex | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > examples.tex
+
+Makefile.deps: Makefile depend.py
+	python depend.py $(EXAMPLES) > Makefile.deps
+
+-include Makefile.deps
+
+examples.tar.gz: examples.pdf examples $(DOCS)
+	tar czf examples.tar.gz examples $(DOCS)
+
+classes: classes.c $(top_srcdir)/src/init.c
+	$(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(INCLUDES) -DFTT_2D=1 \
+	classes.c -o classes $(GFS2D_LIBS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/examples/boussinesq/boussinesq.gfs b/doc/examples/boussinesq/boussinesq.gfs
new file mode 100644
index 0000000..5a8e4b0
--- /dev/null
+++ b/doc/examples/boussinesq/boussinesq.gfs
@@ -0,0 +1,99 @@
+# Title: Boussinesq flow generated by a heated cylinder
+#
+# Description:
+#
+# The classical Boussinesq approximation is applied to solve the flow
+# generated by a heated cylinder. 
+#
+# A source term proportional to a diffusive tracer is added to the
+# vertical component of the velocity field.
+#
+# Adaptivity is used to generate a "sponge" outflow condition on the
+# top boundary.
+#
+# The turbulent plume obtained is illustrated on Figure \ref{tracer}.
+#
+# The movie is generated using the scripting mode of GfsView.
+#
+# \begin{figure}[htbp]
+# \caption{\label{tracer}MPEG movie of the tracer field.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=0.3\hsize]{t.eps}}{t.mpg}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D boussinesq.gfs | gfsview2D boussinesq.gfv | ppm2mpeg > t.mpg
+# Version: 1.1.2
+# Required files: boussinesq.gfv
+# Running time: 60 minutes
+# Generated files: t.mpg t.eps
+#
+3 2 GfsSimulation GfsBox GfsGEdge {} {
+  # Limit the maximum timestep to 1e-2 so that the initial diffusion
+  # is properly resolved
+  Time { end = 20 dtmax = 1e-2 }
+
+  # Use an initial refinement of 8 levels around the solid boundary
+  RefineSolid 8
+
+  # Insert the solid boundary defined implicitly by the 
+  # ellipse() function
+  Solid (ellipse(0.,-0.15,1./16.,1./16.))
+
+  # Add a passive tracer called T
+  VariableTracer T
+
+  # Add diffusion to tracer T
+  SourceDiffusion T 0.0001
+ 
+  # Add a source term to the vertical velocity component equal to T
+  Source V T
+
+  # Dirichlet boundary condition for T on the cylinder
+  SurfaceBc T Dirichlet 1
+
+  # Adapt the mesh using the vorticity criterion at every timestep
+  # down to a maximum level of 8 if y is smaller than 1.5, 0
+  # otherwise.  The topmost part of the domain will not be refined and
+  # will act as a very efficient "sponge" layer to damp any eddies
+  # before they exit the domain.
+  AdaptVorticity { istep = 1 } { maxlevel = (y > 1.5 ? 0 : 8) cmax = 1e-2 }
+
+  # Also adapt according to the tracer gradient
+  AdaptGradient { istep = 1 } { maxlevel = 8 cmax = 5e-2 } T
+
+  # Writes the time and timestep every 10 timesteps on standard error
+  OutputTime { istep = 10 } stderr
+
+  # Writes the simulation size every 10 timesteps on standard error
+  OutputBalance { istep = 10 } stderr
+
+  # Writes info about the convergence of the Poisson solver on standard error
+  OutputProjectionStats { istep = 10 } stderr
+
+  # Outputs profiling information at the end of the simulation to standard error
+  OutputTiming { start = end } stderr
+
+  # Outputs the simulation every 4 timesteps
+  OutputSimulation { istep = 4 } stdout
+ 
+  # Every 4 timesteps, GfsView will read the following command, after having read
+  # the simulation file and will output a PPM screenshot on its standard output
+  EventScript { istep = 4 } { echo "Save stdout { width = 256 height = 512 }" }
+ 
+  # At t = 19, GfsView will create the PPM file used in the doc.
+  EventScript { start = 19 } { echo "Save t.ppm { width = 256 height = 512 }" }
+
+  # At the end of the simulation this file is converted to EPS.
+  EventScript { start = end } { convert -colors 256 t.ppm t.eps ; rm -f t.ppm }
+}
+# The bottom boundary will also allow inflow (despite its name)
+GfsBox { bottom = BoundaryOutflow }
+GfsBox {}
+# The top boundary is a simple outflow condition. This could cause problems
+# (eddies getting stuck on the boundary) if the adaptive "sponge" layer was not
+# used.
+GfsBox { top = BoundaryOutflow }
+1 2 top
+2 3 top
diff --git a/doc/examples/classes.c b/doc/examples/classes.c
new file mode 100644
index 0000000..d8ba6fb
--- /dev/null
+++ b/doc/examples/classes.c
@@ -0,0 +1,43 @@
+#include <string.h>
+#include "init.h"
+#define WIKI "http\\://gfs.sf.net/wiki/index.php/"
+
+static void key_value_pair (const char * key, FILE * lang)
+{
+  fprintf (lang, "gfs_keyword = \"%s\"\n", key);
+  /* keywords must start with Gfs */
+  g_assert (strstr (key, "Gfs") == key);
+  fprintf (lang, "gfs_keyword = \"%s\"\n", &(key[3]));
+}
+
+int main (int argc, char * argv[])
+{
+  GtsObjectClass ** klass;
+
+  klass = gfs_classes ();
+
+  printf ("# Language file for source-highlight\n"
+	  "# Generated automatically by classes.c\n"
+	  "\n");
+
+  key_value_pair ("GfsDefine", stdout);
+  key_value_pair ("GfsProjectionParams", stdout);
+  key_value_pair ("GfsApproxProjectionParams", stdout);
+
+  /* Map module  */
+  key_value_pair ("GfsMapProjection", stdout);
+
+  while (*klass) {
+    key_value_pair ((*klass)->info.name, stdout);
+    klass++;
+  }
+  
+  printf ("\n"
+	  "include \"cpp.lang\"\n"
+	  "\n"
+	  "comment start \"#\"\n"
+	  "\n"
+	  "redef preproc = \"C preprocessor command is not compatible with"
+	  " the use of # as comment character in GTS\"\n");
+  return 0;
+}
diff --git a/doc/examples/crossref.sh.in b/doc/examples/crossref.sh.in
new file mode 100644
index 0000000..aef3422
--- /dev/null
+++ b/doc/examples/crossref.sh.in
@@ -0,0 +1,66 @@
+#!/bin/sh 
+# Generated automatically. Please modify crossref.sh.in.
+
+path="@prefix@/share/gerris"
+
+usage()
+{
+	cat <<EOF
+Usage: crossref.sh [OPTIONS] FILE1 FILE2...
+
+Creates cross-references
+
+Options:
+	[--url=URL] reference URL
+        [--help]    displays this message and exits
+EOF
+	exit $1
+}
+
+if test $# -lt 1; then
+	usage 1 1>&2
+fi
+
+while test $# -gt 1; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --url=*)
+      url=$optarg
+      ;;
+    --help)
+      usage 0 1>&2
+      ;;
+    --*)
+      usage 0 1>&2
+      ;;
+      *)
+      break
+      ;;
+  esac
+  shift
+done
+
+keywords=`awk '{if ($1 == "gfs_keyword" && substr ($3,1,4) == "\"Gfs") print substr($3,2,length($3)-2); }' < $path/gfs.lang`
+
+if test -d references; then :
+else
+    mkdir references
+fi
+
+for k in $keywords; do
+    rm -f references/$k.html
+    for f in $*; do
+	gfsxref --url="$url/$f.html" $k < $f/$f.gfs >> references/$k.html
+	cd $f
+	for d in *; do
+	    if test -d $d; then
+		gfsxref --url="$url/$f.html#$d" $k < $d/$d.gfs >> ../references/$k.html
+	    fi
+	done
+	cd ..
+    done
+done
diff --git a/doc/examples/cylinder/cylinder.gfs b/doc/examples/cylinder/cylinder.gfs
new file mode 100644
index 0000000..cc22611
--- /dev/null
+++ b/doc/examples/cylinder/cylinder.gfs
@@ -0,0 +1,137 @@
+# Title: B\'enard--von K\'arm\'an Vortex Street for flow around a cylinder at Re=160
+#
+# Description:
+#
+# An example of 2D viscous flow around a simple solid boundary. Fluid
+# is injected to the left of a channel bounded by solid walls with a
+# slip boundary condition. A passive tracer is injected in the bottom
+# half of the inlet.
+#
+# Adaptive refinement is used based on both the vorticity and the
+# gradient of the passive tracer.
+#
+# After an initial growth phase, a classical B\'enard--von K\'arman
+# vortex street is formed.
+#
+# The results are visualised using MPEG movies of the vorticity
+# (Figure \ref{vorticity}) and tracer concentration (Figure
+# \ref{tracer}) generated on-the-fly.
+#
+# \begin{figure}[htbp]
+# \caption{\label{vorticity}MPEG movie of the vorticity field.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=\hsize]{vort.eps}}{vort.mpg}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{tracer}MPEG movie of the tracer field.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=\hsize]{t.eps}}{t.mpg}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D cylinder.gfs
+# Version: 1.1.0
+# Required files:
+# Running time: 32 minutes
+# Generated files: t.mpg vort.mpg t.eps vort.eps
+#
+# The simulation domain has 8 GfsBox linked by 7 GfsGEdge
+8 7 GfsSimulation GfsBox GfsGEdge {} {
+
+  # Stop the simulation at t = 15
+  Time { end = 15 }
+
+  # Use an initial refinement of 6 levels (i.e. 2^6=64x64 for each box)
+  Refine 6
+
+  # Insert the solid boundary defined as x*x + y*y - 0.0625*0.0625 = 0
+  # (i.e. a cylinder of radius 0.0625 centered on the origin)
+  Solid (x*x + y*y - 0.0625*0.0625)
+
+  # Add a passive tracer called T
+  VariableTracer {} T
+
+  # Set the initial x-component of the velocity to 1
+  Init {} { U = 1 }
+
+  # Adapt the mesh using the vorticity criterion at every timestep
+  # down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptVorticity { istep = 1 } { maxlevel = 6 cmax = 1e-2 }
+
+  # Adapt the mesh using the gradient criterion on variable T at
+  # every timestep, down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptGradient { istep = 1 } { maxlevel = 6 cmax = 1e-2 } T
+
+  # Set a viscosity source term on the velocity vector with x-component U
+  # The Reynolds number is Re = D*U/Nu = 0.125*1/0.00078125 = 160
+  # where D is the cylinder diameter (as defined in cylinder.gts)
+  SourceDiffusion {} U 0.00078125
+  SourceDiffusion {} V 0.00078125
+
+  # Writes the time and timestep every 10 timesteps on standard error
+  OutputTime { istep = 10 } stderr
+
+  # Writes the simulation size every 10 timesteps on standard error
+  OutputBalance { istep = 10 } stderr
+
+  # Writes info about the convergence of the Poisson solver on standard error
+  OutputProjectionStats { istep = 10 } stderr
+
+  # Pipes a bitmap PPM image representation of the vorticity field at every other timestep
+  # into a conversion pipeline to create a MPEG movie called vort.mpg
+  # Sets the minimum used for colormapping to -10 and the maximum to 10
+  OutputPPM { istep = 2 } { ppm2mpeg > vort.mpg } {
+    min = -10 max = 10 v = Vorticity 
+  }
+
+  # Pipes a bitmap PPM image representation of the T field at every other timestep
+  # into a MJPEGTools conversion pipeline to create a MPEG movie called t.mpg
+  # Sets the minimum used for colormapping to 0 and the maximum to 1
+  OutputPPM { istep = 2 } { ppm2mpeg > t.mpg } {
+    min = 0 max = 1 v = T
+  }
+
+  # Pipes a bitmap PPM image representation of the vorticity field at time 15
+  # into the ImageMagick converter "convert" to create the corresponding EPS file
+  OutputPPM { start = 15 } { convert -colors 256 ppm:- vort.eps } {
+    min = -10 max = 10 v = Vorticity
+  }
+
+  # Pipes a bitmap PPM image representation of the T field at time 15
+  # into the ImageMagick converter "convert" to create the corresponding EPS file
+  OutputPPM { start = 15 } { convert -colors 256 ppm:- t.eps } {
+    min = 0 max = 1 v = T
+  }
+
+  # Outputs profiling information at the end of the simulation to standard error
+  OutputTiming { start = end } stderr
+
+}
+GfsBox {
+  # Left boundary on the leftmost box is:
+  #   Dirichlet U=1 for the x-component of the velocity
+  #   Dirichlet T = 1 if y < 0, 0 otherwise
+  left = Boundary {
+    BcDirichlet U 1
+    BcDirichlet T { return y < 0. ? 1. : 0.; }
+  }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+# Right boundary on the rightmost box is outflow
+GfsBox { right = BoundaryOutflow }
+# All the boxes are linked by left to right links
+1 2 right
+2 3 right
+3 4 right
+4 5 right
+5 6 right
+6 7 right
+7 8 right
diff --git a/doc/examples/cylinder/heated/heated.gfs b/doc/examples/cylinder/heated/heated.gfs
new file mode 100644
index 0000000..efe6d5c
--- /dev/null
+++ b/doc/examples/cylinder/heated/heated.gfs
@@ -0,0 +1,114 @@
+# Title: Vortex street around a "heated" cylinder
+#
+# Description:
+#
+# Same as the previous example but this time the tracer is "passive
+# temperature" (i.e. the change in density due to heating is assumed to be
+# negligible).
+#
+# This is an example on how to solve an advection--diffusion equation
+# for a tracer with Dirichlet boundary conditions on an immersed solid
+# boundary.
+#
+# \begin{figure}[htbp]
+# \caption{\label{tracer}MPEG movie of the tracer field.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=\hsize]{t.eps}}{t.mpg}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D heated.gfs
+# Version: 1.1.0
+# Required files:
+# Running time: 22 minutes
+# Generated files: t.mpg t.eps
+#
+# The simulation domain has 8 GfsBox linked by 7 GfsGEdge
+8 7 GfsSimulation GfsBox GfsGEdge {} {
+
+  # Stop the simulation at t = 15
+  Time { end = 15 }
+
+  # Use an initial refinement of 6 levels (i.e. 2^6=64x64 for each box)
+  Refine 6
+
+  # Insert the solid boundary defined as x*x + y*y - 0.0625*0.0625 = 0
+  # (i.e. a cylinder of radius 0.0625 centered on the origin)
+  Solid (x*x + y*y - 0.0625*0.0625)
+
+  # Add a passive tracer called T
+  VariableTracer {} T
+
+   # Add diffusion to tracer T
+  SourceDiffusion {} T 0.001
+
+  # Dirichlet boundary condition for T on the cylinder
+  SurfaceBc T Dirichlet 1
+
+  # Set the initial x-component of the velocity to 1
+  Init {} { U = 1 }
+
+  # Adapt the mesh using the vorticity criterion at every timestep
+  # down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptVorticity { istep = 1 } { maxlevel = 6 cmax = 1e-2 }
+
+  # Adapt the mesh using the gradient criterion on variable T at
+  # every timestep, down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptGradient { istep = 1 } { maxlevel = 6 cmax = 1e-2 } T
+
+  # Set a viscosity source term on the velocity vector with x-component U
+  # The Reynolds number is Re = D*U/Nu = 0.125*1/0.00078125 = 160
+  # where D is the cylinder diameter (as defined in cylinder.gts)
+  SourceDiffusion {} U 0.00078125
+  SourceDiffusion {} V 0.00078125
+
+  # Writes the time and timestep every 10 timesteps on standard error
+  OutputTime { istep = 10 } stderr
+
+  # Writes the simulation size every 10 timesteps on standard error
+  OutputBalance { istep = 10 } stderr
+
+  # Writes info about the convergence of the Poisson solver on standard error
+  OutputProjectionStats { istep = 10 } stderr
+
+  # Pipes a bitmap PPM image representation of the T field at every other timestep
+  # into a conversion pipeline to create a MPEG movie called t.mpg
+  # Sets the minimum used for colormapping to 0 and the maximum to 0.4
+  OutputPPM { istep = 2 } { ppm2mpeg > t.mpg } {
+    min = 0 max = 0.4 v = T
+  }
+
+  # Pipes a bitmap PPM image representation of the T field at time 15
+  # into the ImageMagick converter "convert" to create the corresponding EPS file
+  OutputPPM { start = 15 } { convert -colors 256 ppm:- t.eps } {
+    min = 0 max = 0.4 v = T
+  }
+
+  # Outputs profiling information at the end of the simulation to standard error
+  OutputTiming { start = end } stderr
+
+}
+GfsBox {
+  # Left boundary on the leftmost box is:
+  #   Dirichlet U=1 for the x-component of the velocity
+  left = Boundary {
+    BcDirichlet U 1
+  }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+# Right boundary on the rightmost box is outflow
+GfsBox { right = BoundaryOutflow }
+# All the boxes are linked by left to right links
+1 2 right
+2 3 right
+3 4 right
+4 5 right
+5 6 right
+6 7 right
+7 8 right
diff --git a/doc/examples/cylinder/parallel/parallel.gfs b/doc/examples/cylinder/parallel/parallel.gfs
new file mode 100644
index 0000000..55c7f91
--- /dev/null
+++ b/doc/examples/cylinder/parallel/parallel.gfs
@@ -0,0 +1,137 @@
+# Title: Parallel simulation on four processors
+#
+# Description:
+#
+# The simulation is run in parallel on four processors. Load balancing
+# is used to dynamically redistribute the elements across processors
+# in order to maintain roughly equal mesh sizes on each processor as
+# the resolution varies due to adaptive mesh refinement.
+#
+# \begin{figure}[htbp]
+# \caption{\label{pid}MPEG movie of the processor number
+# assigned to each cell (colour field) together with isolines of
+# vorticity.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=\hsize]{pid.eps}}{pid.mpg}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{balance}Number of elements per processor as a
+# function of time.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{balance.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh parallel.sh
+# Version: 090713
+# Required files: parallel.sh pid.gfv
+# Running time: 32 minutes
+# Generated files: pid.mpg pid.eps balance.eps
+#
+8 7 GfsSimulation GfsBox GfsGEdge {} {
+
+  # Stop the simulation at t = 15
+  Time { end = 15 }
+
+  # Insert the solid boundary defined as x*x + y*y - 0.0625*0.0625 = 0
+  # (i.e. a cylinder of radius 0.0625 centered on the origin)
+  Solid (x*x + y*y - 0.0625*0.0625)
+
+  # Use an initial refinement of 6 levels (i.e. 2^6=64x64 for each
+  # box) only around the solid boundary
+  RefineSolid 6
+
+  # Add a passive tracer called T
+  VariableTracer {} T
+
+  # Set the initial x-component of the velocity to 1
+  Init {} { U = 1 }
+
+  # Adapt the mesh using the vorticity criterion at every timestep
+  # down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptVorticity { istep = 1 } { maxlevel = 6 cmax = 1e-2 }
+
+  # Adapt the mesh using the gradient criterion on variable T at
+  # every timestep, down to a maximum level of 6 and with a maximum tolerance of 1e-2
+  AdaptGradient { istep = 1 } { maxlevel = 6 cmax = 1e-2 } T
+
+  # Set a viscosity source term on the velocity vector
+  # The Reynolds number is Re = D*U/Nu = 0.125*1/0.00078125 = 160
+  # where D is the cylinder diameter (as defined in cylinder.gts)
+  SourceViscosity 0.00078125
+
+  # Balance the number of elements across parallel subdomains at every
+  # timestep if the imbalance is larger than 0.1 (i.e. 10% difference
+  # between the largest and smallest subdomains).
+  EventBalance { istep = 1 } 0.1
+
+  # Writes the time and timestep every 10 timesteps on standard error
+  OutputTime { istep = 10 } stderr
+
+  # Writes the time and simulation balance every timestep in 'balance'
+  OutputTime { istep = 1 } balance
+  OutputBalance { istep = 1 } balance
+
+  # Writes info about the convergence of the Poisson solver on standard error
+  OutputProjectionStats { istep = 10 } stderr
+
+  # Outputs the simulation to standard output every 0.05 time unit
+  OutputSimulation { step = 0.05 } stdout
+  
+  # Sends a command to gfsview on standard output to save PPM images
+  EventScript { step = 0.05 } {
+      echo "Save stdout { width = 1600 height = 200 }" 
+  }
+
+  # Outputs profiling information at the end of the simulation to standard error
+  OutputTiming { start = end } stderr
+
+  # Generate graphics
+  OutputSimulation { start = end } end.gfs
+  EventScript { start = end } {
+      echo "Save pid.eps { format = EPS width = 800 height = 100 line_width = 0.2 }" | \
+	  gfsview-batch2D end.gfs pid.gfv
+      awk '{
+        if ($1 == "step:")
+          t = $4;
+        else if ($1 == "domain")
+          print t, 100.*($9/$3 - 1.), $3, $5, $9;
+      }' < balance > balance1
+      cat <<EOF | gnuplot
+      set term postscript eps lw 3 solid 20 colour
+      set output 'balance.eps'
+      set xlabel 'Time'
+      set ylabel 'Number of elements per processor'
+      set key bottom right
+      plot 'balance1' u 1:3 w l t 'minimum', '' u 1:4 w l t 'average', '' u 1:5 w l t 'maximum'
+EOF
+  }
+}
+GfsBox {
+  # Left boundary on the leftmost box is:
+  #   Dirichlet U=1 for the x-component of the velocity
+  #   Dirichlet T = 1 if y < 0, 0 otherwise
+  left = Boundary {
+    BcDirichlet U 1
+    BcDirichlet T { return y < 0. ? 1. : 0.; }
+  }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+# Right boundary on the rightmost box is outflow
+GfsBox { right = BoundaryOutflow }
+# All the boxes are linked by left to right links
+1 2 right
+2 3 right
+3 4 right
+4 5 right
+5 6 right
+6 7 right
+7 8 right
diff --git a/doc/examples/dam/dam.gfs b/doc/examples/dam/dam.gfs
new file mode 100644
index 0000000..f251b24
--- /dev/null
+++ b/doc/examples/dam/dam.gfs
@@ -0,0 +1,87 @@
+# Title: Dam break on complex topography
+#
+# Description:
+#
+# An example similar to that
+# \htmladdnormallinkfoot{presented}{http://www.amath.washington.edu/~rjl/catalina/leveque1.pdf}
+# by Randall J. LeVeque illustrating the solution of the
+# \htmladdnormallinkfoot{Saint-Venant}{http://en.wikipedia.org/wiki/Shallow\_water\_equations}
+# (or shallow-water) equations with complex topography, wetting and
+# drying, shocks and hydrostatic equilibrium.
+#
+# \begin{figure}[htbp]
+# \caption{Topography (red) and animation of the water level (blue).}
+# \begin{rawhtml}
+# <DIV CLASS="center">
+# <IMG SRC="dam/dam.gif">
+# </DIV>
+# \end{rawhtml}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D dam.gfs
+# Version: 1.3.1
+# Required files: dam.plot
+# Running time: 2 minutes
+# Generated files: dam.gif
+#
+# Use the GfsRiver Saint-Venant solver
+1 0 GfsRiver GfsBox GfsGEdge {} {
+    PhysicalParams { L = 8. }
+    RefineSolid 9
+
+    # Set a solid boundary close to the top boundary to limit the
+    # domain width to one cell (i.e. a 1D domain)
+    Solid (y/8. + 1./pow(2,9) - 1e-6 - 0.5)
+
+    # Set the topography Zb and the initial water surface elevation P
+    Init {} {
+	Zb = x*x/8.+cos(M_PI*x)/2.
+	P = {
+	    double p = x > 0. ? 0.35 : x < -2. ? 1.9 : -1.;
+	    return MAX (0., p - Zb);
+	}
+    }
+    PhysicalParams { g = 1. }
+
+    # Use a first-order scheme rather than the default second-order
+    # minmod limiter. This is just to add some numerical damping.
+    AdvectionParams {
+       # gradient = gfs_center_minmod_gradient
+	gradient = none
+    }
+
+    Time { end = 40 }
+    OutputProgress { istep = 10 } stderr
+    OutputScalarSum { istep = 10 } ke { v = (P > 0. ? U*U/P : 0.) }
+    OutputScalarSum { istep = 10 } vol { v = P }
+    OutputScalarNorm { istep = 10 } u { v = (P > 0. ? U/P : 0.) }
+
+    # Save a text-formatted simulation
+    OutputSimulation { step = 0.5 } sim-%g.txt { format = text }
+
+    # Use gnuplot to create gif images
+    EventScript { step = 0.5 } {
+	time=`echo $GfsTime | awk '{printf("%4.1f\n", $1);}'`
+	cat <<EOF | gnuplot
+load 'dam.plot'
+set title "t = $time"
+set term postscript eps color 14
+set output "sim.eps"
+plot [-4.:4.]'sim-$GfsTime.txt' u 1:7:8 w filledcu lc 3, 'sim-0.txt' u 1:7 w l lw 4 lc 1 lt 1
+EOF
+	time=`echo $GfsTime | awk '{printf("%04.1f\n", $1);}'`
+	convert -density 300 sim.eps -trim +repage -bordercolor white -border 10 -resize 640x282! sim-$time.gif
+	rm -f sim.eps
+    }
+
+    # Combine all the gif images into a gif animation using gifsicle
+    EventScript { start = end } {
+	gifsicle --colors 256 --optimize --delay 25 --loopcount=0 sim-*.gif > dam.gif
+	rm -f sim-*.gif sim-*.txt
+    }
+}
+GfsBox {
+    left = Boundary
+    right = Boundary
+}
diff --git a/doc/examples/depend.py b/doc/examples/depend.py
new file mode 100644
index 0000000..dc18220
--- /dev/null
+++ b/doc/examples/depend.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+import gfs2tex
+
+dists = ""
+depends = ""
+docs = ""
+
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            example = gfs2tex.Example(root)
+            name = example.path + "/" + example.name + ".gfs"
+            docs += "\\\n\t" + name + ".html"
+            dists += "\\\n\t" + name
+            depends += "\\\n\t" + name
+            for f in example.required:
+                if os.path.exists("../../_darcs/current/doc/examples/" + example.path + "/" + f):
+                    dists += "\\\n\t" + example.path + "/" + f
+            for f in example.generated:
+                depends += "\\\n\t" + example.path + "/" + f
+                if f[-4:] == ".mpg":
+                    docs += "\\\n\t" + example.path + "/" + f
+
+print "DOCS = " + docs + dists
+print ""
+print "EXTRA_DIST += " + dists
+print ""
+print "examples.tex: " + depends
diff --git a/doc/examples/garden/garden.gfs b/doc/examples/garden/garden.gfs
new file mode 100644
index 0000000..ef268e8
--- /dev/null
+++ b/doc/examples/garden/garden.gfs
@@ -0,0 +1,121 @@
+# Title: "Garden sprinkler effect" in wave model
+#
+# Description:
+#
+# The wave model is used to reproduce the classical "Garden Sprinkler
+# Effect" (GSE), a numerical artifact of the discrete directions of
+# wave propagation (see Tolman, 2002).
+#
+# A spatially-Gaussian wave spectrum is initialised in a 5000
+# km-squared domain. The other parameters are those of Tolman, 2002.
+#
+# The final (t = 5 days) significant wave height for different model
+# runs is illustrated in Figure \ref{end}. The interval between the
+# isolines is 0.1 metres as in Figure 1 of Tolman, 2002. For a small
+# number of discrete directions (24), the GSE is evident and the
+# results closely match those of Tolman both for the constant
+# resolution and the adaptive version of the code. For larger number
+# of directions (60 and 120), the results do not show any obvious GSE
+# and match the corresponding results of Tolman (Figure 1.b of Tolman,
+# 2002 but note that the spatial resolution of Tolman is finer, 25 km
+# rather than 78 km here).
+#
+# \begin{figure}[htbp]
+# \caption{\label{end}Final (t = 5 days) significant wave height for
+# different model runs.}
+# \begin{center}
+# \includegraphics[width=\hsize]{end.eps}
+# \end{center}
+# \end{figure}
+#
+# The evolution in time of the significant wave height together with
+# the corresponding adaptive discretisation is illustrated in Figure
+# \ref{mesh} for 120 directions. The mesh is adapted according to the
+# spatial gradient in the significant wave height. This results in
+# substantial savings in computational cost as illustrated by the
+# timings given in Table \ref{cpu}. The computational cost with 120
+# directions is comparable to the cost with 24 directions on a regular
+# (i.e. non-adaptive) mesh. This demonstrates that the GSE can be
+# alleviated -- at comparable computational cost -- by combining
+# adaptive refinement with a refined discretisation in direction
+# space.
+#
+# \begin{figure}[htbp]
+# \caption{\label{mesh}Evolution of the significant wave height and
+# adaptive mesh. 120 directions.}
+# \begin{center}
+# \includegraphics[width=\hsize]{mesh.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{table}[htbp]
+# \caption{\label{cpu}CPU time for the four models of Figure \ref{end}.}
+# \begin{center}
+# \input{cpu.tex}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh garden.sh
+# Version: 1.2.1
+# Required files: garden.sh end.gfv mesh.gfv
+# Running time: 41 minutes
+# Generated files: end.eps mesh.eps cpu.tex
+#
+1 0 GfsWave GfsBox GfsGEdge {} {
+    Refine 6
+
+    # Default time units for wave model is hours
+    # 120 hours = 5 days
+    Time { end = 120 }
+
+    # Default length units for wave model is km
+    PhysicalParams { L = 5000 }
+
+    # Define some useful functions
+    Global {
+        /* gaussian distribution */
+        static double gaussian (double f, double fmean, double fsigma) {
+            return exp (-((f - fmean)*(f - fmean))/(2.*fsigma*fsigma));
+        }
+        /* cos(theta)^n distribution */
+        static double costheta (double theta, double thetam, double thetapower) {
+            double a = cos (theta - thetam);
+            return a > 0. ? pow (a, thetapower) : 0.;
+        }
+    }
+
+    # Initialise the wave spectrum
+    InitWave {} {
+        /* This function defines the spectral distribution:
+         * a gaussian in frequency space and 
+         * a cos(theta)^2 distribution in direction space 
+	 */
+        return gaussian (Frequency, 0.1, 0.02)*
+               costheta (Direction, 30.*M_PI/180., 2.);
+    } {
+        /* This function defines the significant wave height:
+         * the energy is a gaussian bump in (x,y) space,
+         * the maximum significant wave height is 2.5 
+	 */
+        x -= -2000.;
+        y -= -2000.;
+        double Hsmax = 2.5;
+        double E = (Hsmax*Hsmax/16.)*gaussian (sqrt (x*x + y*y), 0., 150.);
+        return 4.*sqrt (E);
+    }
+
+    AdaptGradient { istep = 1 } { cmax = 0.04 minlevel = MINLEVEL maxlevel = 6 } Hs
+
+    OutputTime { istep = 1 } log-MINLEVEL-NTHETA
+    OutputScalarStats { step = 12 } hs-MINLEVEL-NTHETA { v = Hs }
+    OutputSimulation { step = 12 } sim-MINLEVEL-NTHETA-%g.gfs
+    EventScript { step = 12 } { gzip -f sim-*-*-*.gfs }
+    OutputSimulation { start = end } end-MINLEVEL-NTHETA.gfs    
+    EventScript { start = end } { gzip -f end-*-*.gfs }
+    OutputPPM { step = 12 } { ppm2mpeg > hs-MINLEVEL-NTHETA.mpg } { v = Hs maxlevel = 7 }
+} {
+    # Number of discretised directions (default is 24)
+    ntheta = NTHETA
+}
+GfsBox {}
diff --git a/doc/examples/gfs-highlight.in b/doc/examples/gfs-highlight.in
new file mode 100644
index 0000000..99b998f
--- /dev/null
+++ b/doc/examples/gfs-highlight.in
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+wiki="http:\/\/gfs.sf.net\/wiki\/index.php"
+title=""
+css="darcs.css"
+
+path="@prefix@/share/gerris"
+
+usage()
+{
+	cat <<EOF
+Usage: gfs-highlight [OPTIONS] < input.gfs > output.html
+
+Syntax highlighting/hypertext linking of Gerris simulation files.
+
+Options:
+	[--title=TITLE] sets the page title
+	[--css=FILE]    sets the CSS stylesheet filename
+        [--comments]    include comment block at the start
+        [--bold]        use bold instead of links
+        [--help]        displays this message and exits
+EOF
+	exit $1
+}
+
+comment=0
+bold=0
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --title=*)
+      title=$optarg
+      ;;
+    --css=*)
+      css=$optarg
+      ;;
+    --comment)
+      comment=1
+      ;;
+    --bold)
+      bold=1
+      ;;
+    --help)
+      usage 0 1>&2
+      ;;
+    *)
+      usage 0 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "x$title" = "x"; then :
+cat <<EOF
+<tt class="gfs">
+EOF
+else
+cat <<EOF
+<html>
+<head>
+<title>$title</title>
+<link rel="stylesheet" type="text/css" href="$css">
+</head>
+<body><tt class="gfs">
+EOF
+fi
+
+file=`mktemp gfs-highlight.XXXXXX`
+ln -s -f $path/gfs.lang $file
+
+awk -v comment=$comment 'BEGIN{ infile=comment } {
+       if ($2 == "Generated" && $3 == "files:") {
+         infile = 1; 
+         while ($1 == "#") getline; 
+         print $0; 
+       }
+       else if (infile) 
+         print $0;
+       else if ($5 == "GfsGEdge") {
+         infile = 1;
+         print $0;
+       }
+     }' | \
+source-highlight --lang-def=$file --out-format=html-css | \
+(
+if test $bold = "1"; then
+    sed "s/\"gfs_keyword\">\(Gfs\)\{0,1\}\([a-zA-Z0-9_]*\)<\/span>/"gfs_keyword"><b>\1\2<\/b><\/span>/g"
+else
+    sed "s/\"gfs_keyword\">\(Gfs\)\{0,1\}\([a-zA-Z0-9_]*\)<\/span>/"gfs_keyword"><a href=\"$wiki\/Gfs\2\">\1\2<\/a><\/span>/g"
+fi
+)
+
+rm -f $file
+
+if test "x$title" = "x"; then :
+cat <<EOF
+</tt>
+EOF
+else
+cat <<EOF
+</tt></body>
+</html>
+EOF
+fi
diff --git a/doc/examples/gfs2doc.in b/doc/examples/gfs2doc.in
new file mode 100644
index 0000000..469b410
--- /dev/null
+++ b/doc/examples/gfs2doc.in
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+
+import sys
+import os
+import stat
+import glob
+import tempfile
+
+sys.path.append("@prefix@/lib/gerris")
+import gfs2tex
+
+if len(sys.argv) < 2:
+    print "usage: gfs2doc DIR1 DIR2..."
+    sys.exit(1)
+
+def myexit(s):
+    os.system("rm -r -f " + wdname)
+    sys.exit(s)
+    
+for d in sys.argv[1:]:
+    example = gfs2tex.Example(d)
+    example.write()
+    wdname = tempfile.mkdtemp()
+    tex = open(wdname + "/" + example.name + ".tex", "w")
+    tex.write(r"""
+    \documentclass[a4paper]{article}
+    \usepackage{hevea}
+    \usepackage[usenames]{color}
+    \usepackage{graphicx}
+    
+    \oddsidemargin=4mm
+    \evensidemargin=-1mm
+    \topmargin=-7mm
+    \textwidth=15.42cm
+    \textheight=23.2cm
+
+    \newcommand{\htmladdnormallinkfoot}[2]{\footahref{#2}{#1}}
+    \newcommand{\htmladdnormallink}[2]{\ahref{#2}{#1}}
+    
+    \begin{document}
+    \section{Examples}
+    """)
+    tex.write(r"\input{" + example.name + "/" + example.name + ".tex" + "}\n")
+    tex.write("\\end{document}\n")
+    tex.close()
+    os.symlink(os.getcwd() + "/" + example.name, wdname + "/" + example.name)
+    if os.system("rm -r -f " + example.name + ".pdf " + example.name + "_html" +\
+              "&& cd " + wdname + \
+              "&& latex -interaction=nonstopmode 2>&1 " + example.name + ".tex" +\
+              "&& latex -interaction=nonstopmode " + example.name + ".tex") or \
+       os.system("cd " + wdname + \
+              "&& dvips -Ppdf -G0 " + example.name + ".dvi -o " + example.name + ".ps" +\
+              "&& ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true " + example.name + ".ps " + example.name + ".pdf" +\
+              "&& mv " + example.name + ".pdf " + os.getcwd()):
+        print "\n\n**** Errors occured while generating file ****: " + example.name + ".pdf"
+        myexit(1)
+        
+    print "\n\n**** Successfully generated file ****: " + example.name + ".pdf\n\n"
+    hname = wdname + "/" + example.name + "_html"
+    os.mkdir(hname)
+    os.symlink("../" + example.name, hname + "/" + example.name)
+    wdir = os.getcwd()
+    if os.system("cd " + wdname + \
+		 "&& hevea -fix " + example.name + ".tex"):
+        print "\n\n**** Errors occured while generating directory ****: " + example.name + "_html"
+        myexit(1)
+    os.system("cd " + wdname + \
+                  "; imagen -res 600 -extra \"pnmscale 0.24\" " + example.name + " " + \
+                  "; mv -f " + example.name + "[0-9][0-9][0-9].png " + example.name + ".html " + \
+                  hname + \
+                  "; mv " + hname + " " + wdir)
+        
+    print "\n\n**** Successfully generated directory ****: " + example.name + "_html\n"
+    files = example.name + "/" + example.name + ".gfs"
+    for f in example.required:
+        files += " " + example.name + "/" + f
+    if os.system("tar czf " + example.name + ".tgz " + files):
+        print "**** Errors occured while generating file ****: " + example.name + ".tgz"
+        os.remove(example.name + ".tgz")
+        myexit(1)
+    status,msg = example.test()
+    if status != None:
+        print "**** Errors occured while generating file ****: " + example.name + ".tgz"
+        print " ".join(msg)
+        os.remove(example.name + ".tgz")
+        myexit(1)
+
+    print "**** Successfully generated file ****: " + example.name + ".tgz"
+    os.system("rm -r -f " + wdname)
diff --git a/doc/examples/gfs2tex b/doc/examples/gfs2tex
new file mode 100644
index 0000000..d2588a0
--- /dev/null
+++ b/doc/examples/gfs2tex
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+import glob
+import gfs2tex
+
+if not os.access("examples",os.F_OK):
+    os.mkdir("examples")
+
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            example = gfs2tex.Example(root)
+            if not os.access("examples/" + example.path,os.F_OK):
+                os.symlink("../" + example.path, "examples/" + example.path)
+            example.write(style="examples.css")
diff --git a/doc/examples/gfs2tex.py b/doc/examples/gfs2tex.py
new file mode 100644
index 0000000..fd3c479
--- /dev/null
+++ b/doc/examples/gfs2tex.py
@@ -0,0 +1,175 @@
+import sys
+import os
+import os.path
+import re
+import tempfile
+
+def generated(lines):
+    for line in lines:
+        record = line.split()
+        if len(record) > 3 and \
+               record[0] == "#" and record[1] == "Generated" and record[2] == "files:":
+            return record[3:]
+    return []
+
+class Example:
+    def __init__(self,path):
+        if path[0:2] == "./":
+            path = path[2:]
+        self.path, self.name = os.path.split(path)
+        if self.name == "":
+            self.name = self.path
+        elif self.path == "":
+            self.path = self.name
+        else:
+            self.path += "/" + self.name
+        self.section = ["\\subsection","\\subsubsection"][self.path.count("/")]
+        file = open(self.path + "/" + self.name + ".gfs")
+        lines = file.readlines()
+        self.generated = generated(lines)
+        if os.access(self.path + "/status", os.R_OK):
+            self.status = open(self.path + "/status").readline()
+            self.generated.append("status")
+        else:
+            self.status = None
+        p = re.compile(r"\\label\{[a-zA-Z0-9_\-]*\}")
+        labels = []
+        for line in lines:
+            for l in re.findall(p,line):
+                labels.append(l[7:-1])
+
+        # adds the full path to references to generated files and makes labels absolute
+        lines1 = []
+        path = self.path.replace("/", "-")
+        for line in lines:
+            for gen in self.generated:
+                line = line.replace("{" + gen + "}", "{" + self.path + "/" + gen + "}")
+            for l in labels:
+                line = line.replace("{" + l + "}", "{" + path + "-" + l + "}")
+            lines1.append(line)
+        lines = lines1
+
+        self.title = []
+        self.description = []
+
+        insthg = None
+        for line in lines:
+            record = line.split()
+            if len(record) > 0 and record[0] == "#":
+                if len(record) > 1:
+                    if record[1] == "Title:":
+                        self.title.append(" ".join(record[2:]))
+                        insthg = self.title
+                    elif record[1] == "Description:":
+                        insthg = self.description
+                    elif record[1] == "Required" and record[2] == "files:":
+                        self.required = record[3:]
+                        insthg = None
+                    elif record[1] == "Command:":
+                        self.command = " ".join(record[2:])
+                        insthg = None
+                    elif record[1] == "Author:":
+                        self.author = " ".join(record[2:])
+                        insthg = None
+                    elif record[1] == "Running" and record[2] == "time:":
+                        self.time = " ".join(record[3:])
+                        insthg = None
+                    elif record[1] == "Version:":
+                        self.version = " ".join(record[2:])
+                        insthg = None
+                    elif not insthg == None:
+                        insthg.append(" ".join(record[1:]))
+                elif not insthg == None:
+                    insthg.append(" ".join(record[1:]))
+
+        if os.access(self.path + "/runtime", os.R_OK):
+            self.runtime = float(open(self.path + "/runtime").readline())
+            self.time = ""
+            m = int(self.runtime/60.)
+            if m > 0:
+                self.time += repr(m) + " minutes"
+            s = int(self.runtime-60.*m)
+            if s > 0:
+                self.time += " " + repr(s) + " seconds"
+            self.generated.append("runtime")
+        else:
+            self.runtime = None
+            
+    def write(self,file=None,style=""):
+        if file == None:
+            file = open(self.path + "/" + self.name + ".tex", 'w')
+	file.write(self.section + "{\\label{" + self.name + "}")
+        if self.status:
+            file.write(self.status)
+	file.write("\n".join(self.title) + "}\n")
+	if self.section == "\\subsection":
+	    file.write("\\cutname{" + self.name + ".html}\n")
+        file.write("\\begin{description}\n")
+        file.write("\\item[Author]" + self.author + "\n")
+        file.write("\\item[Command]" + "{\\tt " + self.command.replace('&',r'\&') + "}\n")
+        file.write("\\item[Version]" + self.version + "\n")
+        f = self.name + ".gfs"
+        required = " " + f + \
+                   " \\htmladdnormallinkfoot{(view)}{" + self.path + "/" + f + ".html}" +\
+                   " \\htmladdnormallinkfoot{(download)}{" + self.path + "/" + f + "}\\\\"
+        for f in self.required:
+            required += " \\htmladdnormallinkfoot{" + f + "}{" + self.path + "/" + f + "}"
+        file.write("\\item[Required files]" + required + "\n")
+        file.write("\\item[Running time]" + self.time + "\n")
+        file.write("\\end{description}\n")
+        file.write("\n".join(self.description))
+        self.colorize(style)
+
+    def colorize(self,style=""):
+        basename = self.path + "/" + self.name
+        if style != "":
+            style = " --css=" + ["../","../../"][self.path.count("/")] + style
+        os.system("gfs-highlight " + \
+                      "--title=" + self.name + ".gfs" + style + \
+                      " < " + basename + ".gfs > " + basename + ".gfs.html")
+
+    def test(self):
+        wdname = tempfile.mkdtemp()
+        path = os.getcwd() + "/" + self.path + "/"
+        files = path + self.name + ".gfs"
+        for f in self.required:
+            files += " " + path + f
+        command = self.command
+        for v in ["2D","2D3","3D"]:
+            command = command.replace("gfsview" + v, "gfsview-batch" + v)
+        out = os.popen("cd " + wdname + " && " +\
+                       "mkdir test && cd test && " +\
+                       "cp -f " + files + " . && " +\
+                       "awk '{ if ($1 == \"Time\" || $1 == \"GfsTime\")" +\
+                       "  print $0 \"\\nTime { iend = 1 }\";" +
+                       "else print $0;"
+                       "}' < " + self.name + ".gfs > " + self.name + ".tmp && " +\
+                       "mv -f " + self.name + ".tmp " + self.name + ".gfs && ( " +\
+		       "bash -c \" set -o pipefail && " + command + "\" ) 2>&1")
+        lines = out.readlines()
+        status = out.close()
+        os.system("rm -r -f " + wdname)
+        if status != None:
+            return status,lines
+        else:
+            return None,None
+
+    def run(self,env=""):
+        out = os.popen("cd " + self.path + " && ( time -p " +\
+                       " bash -c \" set -o pipefail && " + env + " " + self.command + "\" ) 2>&1")
+        lines = []
+        for l in out:
+            record = l.split()
+            if len(record) > 0:
+                if record[0] == "user":
+                    self.runtime = float(record[1])
+                    print >>open(self.path + "/runtime",'w'), self.runtime
+                elif record[0] != "real" and record[0] != "sys":
+                    lines.append(l)
+            else:
+                lines.append(l)
+        status = out.close()
+        if status != None:
+            return status,lines
+        else:
+            return None,None
diff --git a/doc/examples/gfsxref b/doc/examples/gfsxref
new file mode 100644
index 0000000..f17add4
--- /dev/null
+++ b/doc/examples/gfsxref
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+usage()
+{
+	cat <<EOF
+Usage: gfsxref [OPTIONS] KEYWORD < input.gfs > output.html
+
+Creates cross-references for occurences of KEYWORD in input.gfs
+
+Options:
+	[--url=URL] reference URL for input.gfs
+        [--help]    displays this message and exits
+EOF
+	exit $1
+}
+
+if test $# -lt 1; then
+	usage 1 1>&2
+fi
+
+while test $# -gt 1; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --url=*)
+      url=$optarg
+      ;;
+    --help)
+      usage 0 1>&2
+      ;;
+    --*)
+      usage 0 1>&2
+      ;;
+  esac
+  shift
+done
+
+title=`awk --posix -v keyword=$1 '
+BEGIN {
+  if (substr (keyword, 1, 3) == "Gfs")
+    keyword = substr (keyword, 4);
+  paren = -1;
+  n = 0;
+  last = "";
+}
+{
+  if ($1 == "#" && $2 == "Title:") {
+    title = $3;
+    for (i = 4; i <= NF; i++)
+      title = title " " $i;
+  }
+  else if ($1 != "#" && $0 ~ "(^|[[:blank:]])+(Gfs){0,1}" keyword "[[:blank:]]") {
+    if (last != "")
+      block[n++] = last;
+    last = $0;
+    paren = 0;
+    for (i = 2; i <= NF; i++) {
+      if ($i == "#")
+        break;
+      if (index ($i, "{"))
+        paren++;
+      if (index ($i, "}"))
+        paren--;
+    }
+  }
+  else if (paren > 0) {
+    last = last "\n" $0;
+    for (i = 1; i <= NF; i++) {
+      if ($i == "#")
+        break;
+      if (index ($i, "{"))
+        paren++;
+      if (index ($i, "}"))
+        paren--;
+    }
+  }
+} 
+END {
+  print title
+  if (last != "")
+      block[n++] = last;
+  for (i = 0; i < n; i++)
+    print block[i] > "xref_" i;
+}'`
+
+if test -f xref_0; then
+    cat <<EOF
+<li><a href="$url">$title</a></li>
+EOF
+
+    for file in xref_*; do
+	echo "<p>"
+	gfs-highlight --comment --bold < $file
+	echo "</p>"
+    done
+    
+    rm -f xref_*
+fi
diff --git a/doc/examples/hump/hump.gfs b/doc/examples/hump/hump.gfs
new file mode 100644
index 0000000..bf2d467
--- /dev/null
+++ b/doc/examples/hump/hump.gfs
@@ -0,0 +1,104 @@
+# Title: Small amplitude solitary wave interacting with a parabolic hump
+#
+# Description:
+#
+# This test case was proposed by LeVeque (JCP, 1998) as a check for
+# the accuracy of hydrostatic balance for the Saint-Venant equations
+# with variable topography. A solitary wave of small amplitude is
+# generated by an initial discontinuity on the left-hand-side of the
+# domain and moves past a parabolic hump creating complex focusing and
+# diffraction (Figure \ref{hump}). Any inaccuracy in hydrostatic
+# balance will clearly affect the solution given the small amplitude
+# of the initial perturbation.
+#
+# \begin{figure}[htbp]
+# \caption{\label{hump}Animation of the topography (coloured) and free
+# surface (white). The vertical scale is exagerated.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=0.6\hsize]{hump.eps}}{hump.mpg}
+# \end{center}
+# \end{figure}
+#
+# Figure \ref{evolution} illustrates the free surface and
+# corresponding adaptive mesh evolution. This figure agrees well with
+# the results reported by
+# \htmladdnormallinkfoot{LeVeque}{http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.5450}
+# using a non-adaptive high-resolution Godunov method (Figure 7, right
+# column, note that the resolution of the results by LeVeque is
+# slightly larger: $600\times 300$ compared to $512\times 256$ here).
+#
+# \begin{figure}[htbp]
+# \caption{\label{evolution}Evolution of the free surface and adaptive mesh.}
+# \begin{center}
+# \begin{tabular}{cc}
+# \includegraphics[width=0.5\hsize]{iso-0.6.eps} &
+# \includegraphics[width=0.5\hsize]{cells-0.6.eps} \\
+# \multicolumn{2}{c}{$t = 0.6$} \\
+# \includegraphics[width=0.5\hsize]{iso-0.9.eps} &
+# \includegraphics[width=0.5\hsize]{cells-0.9.eps} \\
+# \multicolumn{2}{c}{$t = 0.9$} \\
+# \includegraphics[width=0.5\hsize]{iso-1.2.eps} &
+# \includegraphics[width=0.5\hsize]{cells-1.2.eps} \\
+# \multicolumn{2}{c}{$t = 1.2$} \\
+# \includegraphics[width=0.5\hsize]{iso-1.5.eps} &
+# \includegraphics[width=0.5\hsize]{cells-1.5.eps} \\
+# \multicolumn{2}{c}{$t = 1.5$} \\
+# \includegraphics[width=0.5\hsize]{iso-1.8.eps} &
+# \includegraphics[width=0.5\hsize]{cells-1.8.eps} \\
+# \multicolumn{2}{c}{$t = 1.8$}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D hump.gfs | gfsview2D hump.gfv | ppm2mpeg > hump.mpg
+# Version: 1.3.1
+# Required files: hump.gfv isolines.gfv cells.gfv
+# Running time: 7 minutes
+# Generated files: cells-0.6.eps cells-1.2.eps cells-1.8.eps iso-0.9.eps iso-1.5.eps cells-0.9.eps cells-1.5.eps iso-0.6.eps iso-1.2.eps iso-1.8.eps hump.eps hump.mpg
+#
+# Recenter the reference box on (0.5,0.5) (rather than the default (0,0))
+2 1 GfsRiver GfsBox GfsGEdge { x = 0.5 y = 0.5 } {
+    Refine 8
+    Init {} {
+	# Parabolic hump
+	Zb = 0.8*exp(-5.*(x - 0.9)*(x - 0.9) - 50.*(y - 0.5)*(y - 0.5))
+	# Initial free surface and perturbation
+	P = (0.05 < x && x < 0.15 ? 1.01 : 1) - Zb
+    }
+    PhysicalParams { g = 1 }
+    AdvectionParams { cfl = 0.5 }
+    AdaptGradient { istep = 1 } { 
+	cmax = 1e-4
+	cfactor = 2
+	maxlevel = 8
+	minlevel = 6
+    } (P + Zb)
+    Time { end = 1.8 }
+    OutputTime { istep = 10 } stderr
+    OutputSimulation { istep = 10 } stdout
+    EventScript { istep = 10 } { echo "Save stdout { width = 640 height = 480 }" }
+    OutputSimulation { start = 0.6 step = 0.3 } sim-%g.gfs
+    EventScript { start = end } {
+	for i in 0.6 0.9 1.2 1.5 1.8; do
+	    echo "Save stdout { format = EPS line_width = 0.2 }" | \
+		gfsview-batch2D sim-$i.gfs isolines.gfv > iso-$i.eps
+	    echo "Save stdout { format = EPS line_width = 0.2 }" | \
+		gfsview-batch2D sim-$i.gfs cells.gfv > cells-$i.eps
+	done
+	echo "Save stdout { width = 1280 height = 960 }" | \
+	    gfsview-batch2D sim-0.9.gfs hump.gfv | convert ppm:- hump.eps
+    }
+}
+# "open" boundary conditions on all boundaries
+GfsBox {
+    left = Boundary { BcNeumann U 0 }
+    top = Boundary { BcNeumann V 0 }
+    bottom = Boundary { BcNeumann V 0 }
+}
+GfsBox {
+    right = Boundary { BcNeumann U 0 }
+    top = Boundary { BcNeumann V 0 }
+    bottom = Boundary { BcNeumann V 0 }
+}
+1 2 right
diff --git a/doc/examples/logo/logo.gfs b/doc/examples/logo/logo.gfs
new file mode 100644
index 0000000..0942084
--- /dev/null
+++ b/doc/examples/logo/logo.gfs
@@ -0,0 +1,60 @@
+# Title: Coalescence of a pair of Gaussian vortices (Gerris logo)
+#
+# Description:
+#
+# This example generates the Gerris desktop logo (Figure \ref{logo}).
+#
+# A pair of Gaussian vortices slowly merge. This is the primary
+# mechanism controlling the evolution of two-dimensional turbulence
+# and consequently has been studied in some detail.
+#
+# \begin{figure}[htbp]
+# \caption{\label{logo}Gerris logo and animation.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=0.15\hsize]{logo.eps}}{logo.mpg}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D logo.gfs | gfsview2D logo.gfv
+# Required files: logo.gfv
+# Version: 1.0.0
+# Running time: 5 minutes
+# Generated files: logo.mpg logo.png logo.eps
+#
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Time { end = 4 }
+    Refine 6
+    # Take a large domain to minimise the influence of boundaries but
+    # refine only in a small central disk.
+    Refine (sqrt(x*x + y*y) < 0.0625 ? 12 : 6)
+    # Initialise a vorticity field given by two gaussian distributions
+    InitVorticity {} {
+        /* We use nested functions for simplicity (this will not work on MACOSX) */
+        double vortex (double xc, double yc, double r) {
+            double r2 = (x - xc)*(x - xc) + (y - yc)*(y - yc);
+            return 2.*M_PI*exp (- 2.*r2/(r*r));
+        }
+        double r = 0.01, theta = 30.*M_PI/180.;
+        return vortex (-r*sin(theta), r*cos(theta), 0.01) + 
+               vortex (r*sin(theta), -r*cos(theta), 0.01);
+    }
+    AdaptVorticity { istep = 1 } { cmax = 1e-2 maxlevel = 12 }
+    OutputTime { istep = 1 } stderr
+    OutputProjectionStats { istep = 1 } stderr
+    OutputSimulation { istep = 10 } stdout
+    OutputPPM { istep = 2 } { ppm2mpeg > logo.mpg } {
+        v = Vorticity
+        min = -0.1348 max = 6.22219
+        # Only generate the movie in a small box centered on the origin
+        box = -0.025,-0.025,0.025,0.025
+    }
+    EventScript { start = end } {
+        echo "Save logo.ppm { width = 1024 height = 1024 }"
+        sleep 5 # to wait for GfsView to finish writing the image
+        convert -transparent "#0000FF" logo.ppm -geometry 156x156 logo.png
+        montage -background white -geometry +0+0 logo.png logo.eps
+        rm -f logo.ppm
+    }
+}
+GfsBox {}
diff --git a/doc/examples/rt/rt.gfs b/doc/examples/rt/rt.gfs
new file mode 100644
index 0000000..4b8ef7d
--- /dev/null
+++ b/doc/examples/rt/rt.gfs
@@ -0,0 +1,91 @@
+# Title: Rayleigh-Taylor instability
+#
+# Description:
+#
+# A classical test case for the flow of two fluids of different
+# densities. A sinusoidal interface separates the two fluids. The
+# heavier fluid is on top. A mushroom-shaped instability develops in
+# time as illustrated on Figure \ref{evolution}.
+# 
+# \begin{figure}[htbp]
+# \caption{\label{evolution}Evolution of the interface.}
+# \begin{center}
+# \begin{tabular}{ccccc}
+# \includegraphics[width=0.15\hsize]{t-0.eps} &
+# \includegraphics[width=0.15\hsize]{t-0.7.eps} &
+# \includegraphics[width=0.15\hsize]{t-0.8.eps} &
+# \includegraphics[width=0.15\hsize]{t-0.9.eps} &
+# \includegraphics[width=0.15\hsize]{t-1.eps} \\
+# $t=0$ & $t=0.7$ & $t=0.8$ & $t=0.9$ & $t=1.0$
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{movie}MPEG movies of the tracer and vorticity fields.}
+# \begin{center}
+# \begin{tabular}{cc}
+# \htmladdnormallinkfoot{\includegraphics[width=0.2\hsize]{t.eps}}{t.mpg} &
+# \htmladdnormallinkfoot{\includegraphics[width=0.2\hsize]{vort.eps}}{vort.mpg}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D rt.gfs | gfsview2D rt.gfv
+# Version: 1.1.0
+# Required files: rt.gfv
+# Running time: 12 minutes
+# Generated files: t.mpg vort.mpg t.eps vort.eps t-0.eps t-0.7.eps t-0.8.eps t-0.9.eps t-1.eps
+#
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 1 dtmax = 5e-3 }
+  Refine 7
+
+  # The tracer T is used to track both phases
+  VariableTracerVOF {} T
+ 
+  # The initial sinusoidal interface (translated by 0.5 along the y-axis)
+  InitFraction {} T (0.05*cos (2.*M_PI*x) + y) { ty = 0.5 }
+
+  AdaptVorticity { istep = 1 } { maxlevel = 7 cmax = 2e-2 }
+  AdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T
+
+  # The dynamic viscosity for both phases
+  SourceViscosity {} 0.00313
+
+  # This defines the inverse of the density of the fluids as a
+  # function of T
+  PhysicalParams { alpha = 1./(T*1.225 + (1. - T)*0.1694) }
+
+  # We also need gravity
+  Source {} V -9.81
+
+  OutputTime { istep = 10 } stderr
+  OutputBalance { istep = 10 } stderr
+  OutputProjectionStats { istep = 10 } stderr
+  OutputDiffusionStats { istep = 10 } stderr
+  OutputPPM { istep = 2 } { ppm2mpeg > vort.mpg} {
+    min = -30 max = 30 v = Vorticity
+  }
+  OutputPPM { istep = 2 } { ppm2mpeg > t.mpg } {
+    min = 0 max = 1 v = T
+  }
+  OutputPPM { start = end } { convert -colors 256 ppm:- vort.eps } {
+    min = -30 max = 30 v = Vorticity
+  }
+  OutputPPM { start = end } { convert -colors 256 ppm:- t.eps } {
+    min = 0 max = 1 v = T
+  }
+  OutputTiming { start = end } stderr
+  OutputSimulation { step = 0.1 } stdout
+  EventScript { start = 0 } { echo "Save t-0.eps { format = EPS }" }
+  EventScript { start = 0.7 step = 0.1 } { echo "Save t-$GfsTime.eps { format = EPS }" }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 2 top
+2 3 top
+1 4 bottom
diff --git a/doc/examples/ship/ship.gfs b/doc/examples/ship/ship.gfs
new file mode 100644
index 0000000..43fa8d4
--- /dev/null
+++ b/doc/examples/ship/ship.gfs
@@ -0,0 +1,213 @@
+# Title: Air-water flow around a Series 60 cargo ship
+#
+# Description:
+#
+# The geometrical Volume-Of-Fluid (VOF) advection scheme of Gerris is
+# used to simulate the air-water interface around a ``Series 60 CB=0.6''
+# ship hull. This hull shape is a classical towing tank test case and
+# several experimental dataset are available (see for example the
+# \htmladdnormallinkfoot{University
+# of Iowa web site}{http://www.iihr.uiowa.edu/\~{}shiphydro/efd\_vdata\_S60\_steady.htm}).
+#
+# The liquid is started impulsively from rest to a Froude number of
+# 0.316 corresponding to one of the towing tank cases. The evolution
+# of the interface is illustrated in Figures \ref{closeup} and
+# \ref{front}. After the initial transients have dissipated (Figure
+# \ref{f}), the stationary wave pattern can be compared with the
+# experimental measurements (Figure \ref{comparison}). Adaptivity is
+# used based on the value of vorticity in the liquid only. With the
+# relatively high-resolution used here, damping of the final wave
+# pattern is minimal which illustrates the good energy conservation
+# properties of the overall scheme (but requires a significant amount
+# of CPU time).
+#
+# Only one half of the flow is simulated. The GfsView parameter file
+# {\tt closeup.gfv} shows how to setup the ``Symmetry'' objects
+# to display the full symmetrical flow.
+#
+# \begin{figure}[htbp]
+# \caption{\label{closeup}MPEG movie of the interface
+# evolution. The interface is coloured according to elevation. The
+# vertical scale is exagerated by a factor of three.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=0.8\hsize]{closeup.eps}}{closeup.mpg}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{front}Interface elevation in stationary regime.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{front.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{f}Pressure drag and lift forces on the hull as
+# functions of time.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{f.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{comparison}Interface elevation measured in a towing
+# tank (top-half, University of Iowa dataset) and simulation result
+# (bottom-half). The wave reflection in the experimental data is
+# caused by the lateral wall of the towing tank.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{comparison.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris3D ship.gfs | gfsview-batch3D closeup.gfv | ppm2mpeg -s 640x480 > closeup.mpg
+# Version: 1.2.0
+# Required files: S60-scaled.gts closeup.gfv front.gfv comparison.gfv tank-data.png
+# Running time: 4 days
+# Generated files: closeup.mpg closeup.eps front.eps f.eps comparison.eps
+#
+# Random notes:
+# waveprofile generation:
+# % zcat sim-8.gfs.gz | gfs2oogl3D -c Z -g -o -i | awk '{ if ($4 < 1000) print $1*3.,$2*3.,$3*3.,$4*3.;}' > waveprofile-8
+# Static wetted area for S60-scaled.gts: As = 0.0190254
+#
+3 2 GfsSimulation GfsBox GfsGEdge {} {
+
+    # The wave drag on the hull has strong starting transients,
+    # also the mean wave field takes a relatively long time to
+    # establish.
+    Time { end = 10 }
+
+    # Nine levels is enough to get good agreement with towing tank
+    # data. Adding more levels will reveal finer-scale wave patterns
+    # (but the runs will take even longer...)
+    Global {
+      #define LEVEL 9
+      #define FROUDE 0.316
+      #define RATIO (1.2/1000.)
+      #define VAR(T,min,max) (min + CLAMP(T,0,1)*(max - min))
+    }
+
+    # Translate the model to simulate only half the domain
+    Solid S60-scaled.gts { ty = 0.5 }
+
+    # Refine the hull to LEVEL
+    RefineSolid LEVEL
+    # Refine the water surface to four levels
+    RefineSurface { return 4; } (1e-4 - z)
+
+    VariableTracerVOF T
+    # For high-density ratios we cannot use the volume fraction field
+    # directly to define the density. We need a smoother version.
+    VariableFiltered T1 T 1
+
+    Init {} { U = FROUDE }
+    # Initialise the water surface at z = 1e-4
+    InitFraction T (1e-4 - z)
+
+    # air/water density ratio
+    PhysicalParams { alpha = 1./VAR(T1,RATIO,1.) }
+
+    # Use the reduced gravity approach
+    VariablePosition Z T z
+    # g = 3, g' = 3*(rho1 - rho2)
+    SourceTension T -3.*(1. - RATIO) Z
+
+    # Force the horizontal component of the velocity to relax to
+    # 'FROUDE' (= 0.316) in a band on inflow (x <= -0.375)
+    Source U (x > -0.375 ? 0 : 10.*(FROUDE - U))
+
+    # Adapt the mesh using the vorticity criterion but only in the
+    # water side (T > 0.)
+    # The 'cmax' value can be lowered (e.g. to 1e-2) to increase
+    # the accuracy with which the weaker far-field waves are resolved.
+    AdaptFunction { istep = 1 } {
+        cmax = 1e-2
+        # Faster coarsening than with the default cfactor of 4 reduces
+        # the size of the simulation
+#        cfactor = 2
+        # Coarse 'sponge' for x >= 1.5
+        maxlevel = (x < 1.5 ? LEVEL : 4)
+        minlevel = 4
+    } {
+        return (T > 0.)*fabs (Vorticity)*ftt_cell_size (cell)/FROUDE;
+    }
+
+    # Pressure (i.e. wave drag) force on the hull
+    OutputSolidForce { istart = 1 istep = 1 } f
+
+    OutputTime { istep = 1 } stderr
+    OutputBalance { istep = 1 } stderr
+    OutputProjectionStats { istep = 1 } stderr
+    OutputTiming { istep = 10 } stderr
+
+    # Generation of animations
+    OutputSimulation { istep = 5 end = 4 } stdout
+    EventScript { istep = 5 end = 4 } { echo "Save stdout { width = 1600 height = 1200 }" }
+
+    OutputSimulation { start = 1 step = 1 } sim-%g.gfs
+    # Compresses the saved simulation files
+    EventScript { start = 1 step = 1 } { gzip -f -q sim-*.gfs }
+
+    # Graphics
+    EventScript { start = 10 } {
+        echo "Save stdout { width = 1600 height = 1200 }" | \
+        gfsview-batch3D sim-10.gfs.gz closeup.gfv | \
+        convert -colors 256 ppm:- closeup.eps
+
+        echo "Save stdout { width = 1600 height = 1200 }" | \
+        gfsview-batch3D sim-10.gfs.gz front.gfv | \
+        convert -colors 256 ppm:- front.eps
+
+        echo "Save stdout { width = 800 height = 600 }" | \
+        gfsview-batch3D sim-10.gfs.gz comparison.gfv | \
+        convert -trim ppm:- comparison.ppm
+
+#       echo "Save stdout { width = 800 height = 600 }" | \
+#       gfsview-batch3D sim-10.gfs.gz tank-data.gfv | \
+#       convert -trim -flip ppm:- tank-data.png
+
+        convert tank-data.png tank-data.ppm
+        montage -geometry +0+0 -tile 1x2 tank-data.ppm comparison.ppm png:- | \
+        convert -colors 256 png:- comparison.eps        
+
+        cat <<EOF | gnuplot
+        set term postscript eps lw 3 solid 20 colour
+        set output 'f.eps'
+        set xlabel 'Time'
+        set ylabel 'Force'
+        plot 'f' u 1:(\$2*2.) every 10 w l t 'Drag', 'f' every 10 u 1:(\$4*2.) w l t 'Lift'
+EOF
+    }
+}
+# Impose symmetry conditions on top and bottom boundaries
+# and inflow/outflow conditions on the left and right boundaries
+# (so that emitted gravity waves can leave the domain cleanly)
+GfsBox {
+    left = Boundary {
+        BcDirichlet P 0
+        BcDirichlet V 0
+        BcDirichlet W 0
+        BcNeumann U 0
+        BcNeumann T 0
+    }
+    top = Boundary
+    bottom = Boundary
+}
+GfsBox {
+    top = Boundary
+    bottom = Boundary
+}
+GfsBox {
+    right = Boundary {
+        BcDirichlet P 0
+        BcDirichlet V 0
+        BcDirichlet W 0
+        BcNeumann U 0
+        BcNeumann T 0
+    }
+    top = Boundary
+    bottom = Boundary
+}
+1 2 right
+2 3 right
diff --git a/doc/examples/tangaroa/tangaroa.gfs b/doc/examples/tangaroa/tangaroa.gfs
new file mode 100644
index 0000000..1fd070c
--- /dev/null
+++ b/doc/examples/tangaroa/tangaroa.gfs
@@ -0,0 +1,80 @@
+# Title: Turbulent air flow around RV Tangaroa
+#
+# Description:
+#
+# An example of the simulations described in Popinet, Smith and Stevens
+# (2004), Journal of Atmospheric and Oceanic Technology, 21.
+#
+# \begin{figure}[htbp]
+# \caption{\label{sections}MPEG movie of the adaptive mesh. The two cross-sections are
+# coloured according to the norm of the velocity vector.}
+# \begin{center}
+# \htmladdnormallinkfoot{\includegraphics[width=0.8\hsize]{sections.eps}}{sections.mpg}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris3D tangaroa.gfs | gfsview3D sections.gfv | ppm2mpeg -s 640x480 > sections.mpg
+# Version: 0.9.2
+# Required files: tangaroa.gts sections.gfv
+# Running time: 7 hours
+# Generated files: sections.mpg sections.eps
+#
+2 1 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 2 }
+  # Insert the solid boundary defined explicitly by the
+  # triangulated surface contained in the GTS file tangaroa.gts
+  Solid tangaroa.gts
+  Refine 5
+  RefineSolid 9
+  Init {} { U = 1. }
+
+  # Adapt only in the first GfsBox.
+  # The coarse resolution of the second box acts as an efficient "sponge"
+  # layer to dampen any eddy before it exits the domain.
+  AdaptVorticity { istep = 1 } { maxlevel = (x < 0.5 ? 8 : 0) cmax = 1e-2 }
+
+  OutputSolidStats {} stderr
+  OutputTime { istep = 1 } stderr
+  OutputBalance { istep = 1 } stderr
+  OutputProjectionStats { istep = 1 } stderr
+
+  # Store in SU the integral over time of U
+  # At the end of the simulation SU/(Total integration time) = SU/1.
+  # is the mean velocity
+  EventSum { start = 1 istep = 1 } U SU
+  EventSum { start = 1 istep = 1 } V SV
+  EventSum { start = 1 istep = 1 } W SW
+
+  # Store in SU the integral over time of U^2 (i.e. the variance)
+  EventSum { start = 1 istep = 1 } U*U SU2
+  EventSum { start = 1 istep = 1 } V*V SV2
+  EventSum { start = 1 istep = 1 } W*W SW2
+
+  # Output simulation on standard output (to be read and displayed by GfsView)
+  OutputSimulation { istep = 4 } stdout
+  # Sends a command to GfsView to save a 1024x768 PPM image on standard output
+  EventScript { istep = 4 } { echo "Save stdout { width = 1024 height = 768 }" }
+
+  EventScript { start = 1.5 } { echo "Save sections.ppm { width = 1024 height = 768 }" }
+  EventScript { start = end } {
+      convert -colors 256 sections.ppm sections.eps ; rm -f sections.ppm 
+  }
+
+  OutputSimulation { start = end } simulation-sum {
+      variables = SU,SV,SW,SU2,SV2,SW2
+  }
+  OutputTiming { start = end } stderr
+}
+GfsBox { 
+    left = Boundary {
+	BcDirichlet U 1
+    }
+}
+GfsBox {
+    right = Boundary {
+	BcNeumann U 0
+	BcDirichlet P 0
+    }
+}
+1 2 right
diff --git a/doc/examples/template.tex b/doc/examples/template.tex
new file mode 100644
index 0000000..100fc70
--- /dev/null
+++ b/doc/examples/template.tex
@@ -0,0 +1,107 @@
+\documentclass[a4paper]{article}
+\usepackage{hevea}
+\usepackage{color}
+\usepackage{graphicx}
+
+\oddsidemargin=4mm
+\evensidemargin=-1mm
+\topmargin=-7mm
+\textwidth=15.42cm
+\textheight=23.2cm
+
+\newcommand{\gfsweb}{http://gfs.sf.net}
+\newcommand{\htmladdnormallinkfoot}[2]{\footahref{#2}{#1}}
+\newcommand{\htmladdnormallink}[2]{\ahref{#2}{#1}}
+\renewcommand{\cuttingunit}{subsection}
+
+\title{Gerris examples}
+
+\begin{document}
+
+\mbox{}\vspace{1cm}
+\begin{center}
+{\huge Gerris examples}\\
+{\large Version GFS_VERSION}\\
+\vspace{5mm}
+{\large St\'ephane Popinet\\
+\vspace{5mm}
+\today}
+\vspace{1cm}
+\end{center}
+
+\tableofcontents
+
+\section{Introduction}
+
+This document is a collection of examples contributed by Gerris users and intended to illustrate the range of applications where Gerris is applicable. It should also serve as a useful starting point for customised applications.
+
+The sections in this document are a rough classification of the various applications. In particular, an example appearing in a subsection usually indicates that this example is a relatively small incremental change over the parent example appearing in the section above it.
+
+Gerris parameter files are commented and cross-linked with the \htmladdnormallinkfoot{Object Hierarchy}{\gfsweb/wiki/index.php/Object\_hierarchy} documentation. As a rule, the first examples in the document contain comments for most of the instructions in the parameter file. Latter examples only contain comments for the relevant new instructions or for more complex usage of already introduced instructions.
+
+The indicative running times given are representative of the running time on an Intel 2.4 GHz processor.
+
+The usefulness and quality of this document very much depend on the contributions of users. If you think you have used Gerris in an interesting way which is not already covered by the existing examples, you are very welcome to contribute. Have a look at section \ref{howto} for instructions on how to do so.
+
+\section{2D}
+
+\input{cylinder/cylinder.tex}
+\input{cylinder/heated/heated.tex}
+\input{cylinder/parallel/parallel.tex}
+\input{rt/rt.tex}
+\input{boussinesq/boussinesq.tex}
+\input{logo/logo.tex}
+
+\section{3D}
+
+\input{tangaroa/tangaroa.tex}
+\input{ship/ship.tex}
+
+\section{Shallow-water}
+
+\input{tides/tides.tex}
+
+\section{Saint-Venant (non-linear shallow-water)}
+
+\input{dam/dam.tex}
+\input{hump/hump.tex}
+
+\section{Waves}
+
+\input{garden/garden.tex}
+
+\section{\label{howto}How to write examples}
+
+This document is generated automatically using self-documenting Gerris parameter files. If you look at \htmladdnormallinkfoot{any}{cylinder/cylinder.gfs} of the {\tt .gfs} files in this document you will see that apart from comments on specific instructions, the top of the file contains fields which describe the simulation. They are:
+\begin{description}
+\item[Title:] the title of the simulation.
+\item[Description:] a Latex block of text describing the simulation. It can contain figures, tables, equations etc\dots
+\item[Author:] you.
+\item[Command:] the exact command needed to run the example.
+\item[Version:] the version of Gerris you used (output of {\tt gerris2D -V}).
+\item[Required files:] any file (e.g. GTS files etc\dots) other than the Gerris simulation file required to run the simulation. Try to keep the total size of these files reasonable.
+\item[Running time:] the approximate total running time of the simulation. This is of course machine-dependent but must be appropriately scaled to be representative of the running time on an Intel 2.4 GHz processor.
+\item[Generated files:] any file (movies, images, curves etc\dots) generated by the simulation.
+\end{description}
+Apart from the ``Description:'' field all the fields must fit on a single line just after the field name.
+
+Any extra data you need for the description (e.g. figures as EPS files) must be generated by the simulation. Have a look at other examples to see how this can be done.
+
+Once you have an initial draft for your documented parameter file, you need to package it like this:
+\begin{enumerate}
+\item Choose a short name for your example. This short name should not already be used by any of the examples in this document. Let's say {\tt myexample}.
+\item Create a directory {\tt myexample}.
+\item Copy your parameter file in {\tt myexample/myexample.gfs}. You must use the same name for the directory and the parameter file.
+\item Copy any other file you need (as listed in the ``Required files:'' field) in {\tt myexample}.
+\item Cd to {\tt myexample} and re-run the simulation (using the command listed in the ``Command:'' field) or alternatively copy the previously generated files listed in the ``Generated files:'' field into {\tt myexample}.
+\item Cd to {\tt myexample/..}
+\item\label{gendoc} Generate the HTML and PDF documentation for your example using:
+\begin{verbatim}
+% gfs2doc myexample
+\end{verbatim}
+Note that this script requires \footahref{http://pauillac.inria.fr/\~maranget/hevea/index.html}{hevea}.
+\item Check that the {\tt myexample\_html/index.html} and {\tt myexample.pdf} files are to your liking. If they are not, edit your parameter file and return to \ref{gendoc}.
+\item Send me ({\tt s.popinet at niwa.cri.nz}) your example ({\tt myexample.tgz} as an attachment). Tell me which section, subsection you think it would most naturally fit in (or request a new section). I will then review it and integrate it in this document.
+\end{enumerate}
+
+\end{document}
diff --git a/doc/examples/test.py b/doc/examples/test.py
new file mode 100644
index 0000000..797b612
--- /dev/null
+++ b/doc/examples/test.py
@@ -0,0 +1,32 @@
+import sys
+import os
+import os.path
+import gfs2tex
+
+n = 0
+failed = 0
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            example = gfs2tex.Example(root)
+            status,msg = example.test()
+            if status != None:
+                print "FAIL:",root
+                if len(msg) > 0:
+                    print " ".join(msg)
+                failed += 1
+            else:
+                print "PASS:",root
+            n += 1
+
+if failed:
+    msg = repr(failed) + " of " + repr(n) + " tests failed"
+else:
+    msg = "All " + repr(n) + " tests passed"
+
+print len(msg)*"="
+print msg
+print len(msg)*"="
+
+if failed:
+    sys.exit(1)
diff --git a/doc/examples/tides/tides.gfs b/doc/examples/tides/tides.gfs
new file mode 100644
index 0000000..a092344
--- /dev/null
+++ b/doc/examples/tides/tides.gfs
@@ -0,0 +1,206 @@
+# Title: Lunar tides in Cook Strait, New Zealand
+# 
+# Description:
+#
+# The shallow-water equations are solved using the "ocean" version of
+# Gerris. The tidal elevations for the lunar (M2) component obtained
+# from a larger-area tidal model are imposed as conditions on
+# the boundaries of the domain.
+#
+# The comments in the \htmladdnormallinkfoot{tides.sh}{tides/tides.sh}
+# script describe how to generate the appropriate GTS files from the
+# tidal elevation and bathymetry data.
+#
+# After an initial transient ($t < \approx 1$ day) due to relaxation of
+# the model toward a state consistent with the mathematical model and
+# with the imposed boundary conditions, the model reaches a periodic
+# regime (Figure \ref{periodic}).
+#
+# \begin{figure}[htbp]
+# \caption{\label{periodic}Evolution of the maximum velocity and 
+# elevation with time.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{pv.eps}
+# \end{center}
+# \end{figure}
+#
+# Online harmonic decomposition can then be used to extract the
+# amplitudes and phases of the computed M2 tidal components. The
+# simulation stops automatically when convergence of the harmonic
+# decomposition is reached (Figure \ref{harmcon}).
+#
+# \begin{figure}[htbp]
+# \caption{\label{harmcon}Convergence of the maximum tidal amplitude 
+# (estimated from harmonic decomposition) with time.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{a0.eps}
+# \end{center}
+# \end{figure}
+#
+# The final tidal amplitudes and phases are illustrated in Figures
+# \ref{amplitude} and \ref{phase} respectively. The harmonic
+# decomposition is also applied to the velocity field. The results can
+# be represented as tidal ellipses (Figure \ref{ellipses}) and
+# residual currents (Figure \ref{residual}).
+#
+# Note that the results for this simulation will not be as good as
+# these described in Rym Msadek's \htmladdnormallinkfoot{technical
+# report}{http://gfs.sf.net/tides.pdf} because iterative Flather
+# conditions have not been applied. See the report for details.
+#
+# \begin{figure}[htbp]
+# \caption{\label{amplitude}Tidal amplitude estimated from the harmonic 
+# decomposition. Dark red is 1.4 metres, dark blue is 0.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{amplitude.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{phase}Tidal phase estimated from the harmonic 
+# decomposition. Dark red is 180 degrees, dark blue -180 degrees.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{phase.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{ellipses}Detail of tidal ellipses estimated from the harmonic 
+# decomposition coloured according to maximum current speed. Dark red
+# is 2 metres/sec, dark blue is zero.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{ellipses.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Detail of residual tidal currents estimated from the 
+# harmonic decomposition coloured according to residual current speed. 
+# Dark red is 0.6 metres/sec, dark blue is zero.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh tides.sh
+# Version: 1.3.1
+# Required files: tides.sh bathymetry coefficients amplitude.gfv ellipses.gfv phase.gfv residual.gfv tides.gfv
+# Running time: 2 hours
+# Generated files: a0.eps amplitude.eps ellipses.eps phase.eps pv.eps residual.eps
+
+# M2 tidal frequency. The period is 12h25 (44700 seconds).
+Define M2F (2.*M_PI/44700.)
+
+# M2 tidal elevation
+Define M2(t) (A_amp*cos (M2F*t)+B_amp*sin (M2F*t))
+
+# Use the "GfsOcean" model
+1 0 GfsOcean GfsBox GfsGEdge {} {
+    # Set the timestep to sthg small compared to the tidal period
+    Time { dtmax = 100. }
+
+    # Set the box size to 500 km
+    PhysicalParams { L = 500e3 }
+
+    # Use cartographic projection module
+    GModule map
+
+    # Use a Lambert conformal conic projection centered on 174 degrees
+    # longitude and -40.8 degrees latitude. Rotate the domain 40
+    # degrees counter-clockwise.
+    MapProjection { lon = 174 lat = -40.8 angle = 40 }
+
+    # Refine to six levels
+    Refine 6
+
+    # We want more accuracy in the projection than the default 1e-3
+    ApproxProjectionParams { tolerance = 1e-6 nitermax = 10 }
+
+    # Initialise tidal amplitudes
+    Init {} {
+        A_amp = AM2.gts
+        B_amp = BM2.gts
+    }
+
+    # Bathymetry
+    Solid bath.gts
+
+    # Refine the coastline to 10 levels
+    RefineSurface 10 bath.gts { twod = 1 }
+
+    # Acceleration of gravity
+    PhysicalParams { g = 9.81 }
+
+    # Add Coriolis source term
+    SourceCoriolis -1e-4
+
+    # Bottom friction parameterisation:
+    # Quadratic drag with friction coefficient of 4e-4.
+    Init { istep = 1 } {
+        U = U/(1. + dt*Velocity*4e-4/H)
+        V = V/(1. + dt*Velocity*4e-4/H)
+    }
+
+    # Weak exponential filtering of the velocity field
+    #    EventFilter { istep = 1 } U 40000
+    #    EventFilter { istep = 1 } V 40000
+    
+    # After t=100000, starts on-the-fly harmonic decomposition of the pressure field...
+    EventHarmonic { start = 100000 istep = 10 } P A B Z EP M2F
+    # ... and of the velocity field
+    EventHarmonic { start = 100000 istep = 10 } U AU BU ZU EU M2F
+    EventHarmonic { start = 100000 istep = 10 } V AV BV ZV EV M2F
+
+    # After t=100000, stops the simulation if the variations of the A0
+    # harmonic component are less than 0.025 in 100 timesteps.
+    EventStop { start = 100000 istep = 100 } A0 0.025
+
+    OutputTime { istep = 1 } stderr
+    OutputProjectionStats { istep = 1 } stderr
+
+    # Output solution on standard output every 20 timesteps
+    # for on-the-fly visualisation with GfsView.
+    # Do not include the GTS file for the embedded surface to save bandwidth.
+    OutputSimulation { istep = 20 } stdout { solid = 0 }
+
+    # Output solution in file 'end.gfs' at the end of the simulation
+    OutputSimulation { start = end } end.gfs
+
+    # Output curves using gnuplot
+    EventScript { start = end } {
+        cat <<EOF | gnuplot
+        set term postscript eps lw 3 solid 20 colour
+        set output 'pv.eps'
+        set xlabel 'Time (days)'
+        set ylabel 'Elevation (metres) or Velocity (metres/s)'
+        plot 'p' u (\$3/86400.):(\$9/9.81) w l t "Elevation", \
+             'u' u (\$3/86400.):9 w l t "Velocity"
+        set output 'a0.eps'
+        set ylabel 'Maximum harmonic elevation (metres)'
+        plot [1:]'a0' u (\$3/86400.):(\$9/9.81) w l t ""
+EOF
+    }
+
+    OutputScalarNorm { istep = 1 } p { v = P }
+    OutputScalarNorm { istep = 1 } u { v = Velocity }
+    OutputScalarNorm { istep = 10 } a0 { v = sqrt(A0*A0 + B0*B0) }
+}
+GfsBox {
+    # Use Flather boundary conditions on all boundaries
+    left = Boundary {
+        BcFlather U 0 H P M2(t)
+    }
+    right = Boundary {
+        BcFlather U 0 H P M2(t)
+    }
+    top = Boundary {
+        BcFlather V 0 H P M2(t)
+    }
+    bottom = Boundary {
+        BcFlather V 0 H P M2(t)
+    }
+
+    # This is required for consistent free-surface fluxes
+    front = Boundary
+}
diff --git a/doc/figures/axi.tm b/doc/figures/axi.tm
new file mode 100644
index 0000000..9c46fcd
--- /dev/null
+++ b/doc/figures/axi.tm
@@ -0,0 +1,175 @@
+<TeXmacs|1.0.6.11>
+
+<style|article>
+
+<\body>
+  The incompressible Navier--Stokes equations in cylindrical coordinates are
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t>v<rsub|r>+<frac|1|r>*\<partial\><rsub|r>(r*v<rsub|r><rsup|2>)+\<partial\><rsub|z>(v<rsub|r*>*v<rsub|z>)=-\<partial\><rsub|r>\<phi\>+<frac|1|r>*\<partial\><rsub|r>(r*S<rsub|rr>)+\<partial\><rsub|z>S<rsub|zr>-<frac|S<rsub|\<theta\>\<theta\>>|r>,>|<cell|<eq-number><label|momr>>>|<row|<cell|>|<cell|\<partial\><rsub|t>v<rsub|z>+<frac|1|r>*\<partial\><rsub|r>(r*v<rsub|r>*v<rsub|z>)+\<partial\><rsub|z>(v<rsup|2><rsub|z>)=-\<partial\><rsub|z>\<phi\>+<frac|1|r>*\<partial\><rsub|r>(r*S<rsub|zr>)+\<partial\><rsub|z>S<rsub|zz>,>|<cell|<eq-number><label|momz>>>|<row|<cell|>|<cell|<frac|1|r>*\<partial\><rsub|r>(r*v<rsub|r>)+\<partial\><rsub|z>v<rsub|z>=0,>|<cell|<eq-number><label|continuity>>>>>
+  </eqnarray*>
+
+  with <math|\<phi\>=p/\<rho\>> and the stress tensor
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|S<rsub|rr>>|<cell|=>|<cell|2*\<nu\>*\<partial\><rsub|r>v<rsub|r>,>>|<row|<cell|S<rsub|\<theta\>\<theta\>>>|<cell|=>|<cell|2*\<nu\>*<frac|v<rsub|r>|r>,>>|<row|<cell|S<rsub|zz>>|<cell|=>|<cell|2*\<nu\>*\<partial\><rsub|z>v<rsub|z>,>>|<row|<cell|S<rsub|zr>>|<cell|=>|<cell|\<nu\>*<left|(>\<partial\><rsub|r>v<rsub|z>+\<partial\><rsub|z>v<rsub|r><right|)>.>>>>
+  </eqnarray*>
+
+  Considering a control volume <math|\<Omega\>> with boundary
+  <math|\<partial\>\<Omega\>>, the integral equations can then be written
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t><big|int><rsub|\<Omega\>>v<rsub|r>*r*dr*dz+<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|r>*v<rsub|z>*dr+<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|r>*v<rsub|r>*dz=>|<cell|>>|<row|<cell|>|<cell|-<big|int><rsub|\<partial\>\<Omega\>>\<phi\>*r*dz+<big|int><rsub|\<Omega\>>\<phi\>*dr*dz+<big|int><rsub|\<partial\>\<Omega\>>r*S<rsub|zr>*dr+<big|int><rsub|\<partial\>\<Omega\>>r*S<rsub|rr>*dz-<big|int><rsub|\<Omega\>>S<rsub|\<theta\>\<theta\>>*dr*dz,>|<cell|>>|<row|<cell|>|<cell|\<partial\><rsub|t><big|int><rsub|\<Omega\>>v<rsub|z>*r*dr*dz+<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|z>*v<rsub|z>*dr+<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|z>*v<rsub|r>*dz=>|<cell|>>|<row|<cell|>|<cell|-<big|int><rsub|\<partial\>\<Omega\>>\<phi\>*r*dr+<big|int><rsub|\<partial\>\<Omega\>>r*S<rsub|zz>*dr+<big|int><rsub|\<partial\>\<Omega\>>r*S<rsub|zr>*dz,>|<cell|>>|<row|<cell|>|<cell|<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|z>*dr+<big|int><rsub|\<partial\>\<Omega\>>r*v<rsub|r>*dz=0.>|<cell|>>|<row|<cell|>|<cell|>|<cell|>>>>
+  </eqnarray*>
+
+  Posing
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<with|mode|text|<math|a<rsup|i,j>>>>|<cell|\<equiv\>>|<cell|<big|int><rsub|\<Omega\>>dr*dz,>>|<row|<cell|c<rsup|i,j>>|<cell|\<equiv\>>|<cell|<big|int><rsub|\<Omega\>>r*dr*dz\<approx\>r<rsup|j>*a<rsup|i,j>,>>|<row|<cell|s<rsub|z><rsup|i,j>>|<cell|\<equiv\>>|<cell|<big|int><rsub|\<partial\>\<Omega\><rsup|j>>r*dr\<approx\>r<rsup|j>*<big|int><rsub|\<partial\>\<Omega\><rsup|j>>dr,>>|<row|<cell|s<rsup|i,j-1/2><rsub|r>>|<cell|\<equiv\>>|<cell|<big|int><rsub|\<partial\>\<Omega\><rsup|j-1/2>>r*dz<rsub|>=r<rsup|j-1/2>*<big|int><rsub|\<partial\>\<Omega\><rsup|j-1/2>>dz,>>>>
+  </eqnarray*>
+
+  we get the discrete form of the equations as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t>(c*v<rsub|r>)<rsup|i,j>+(s<rsub|z>*v<rsub|r>*v<rsub|z>)<rsup|i+1/2,j>-(s<rsub|z>*v<rsub|r>*v<rsub|z>)<rsup|i-1/2,j>+(s<rsub|r>*v<rsub|r><rsup|2>)<rsup|i,j+1/2>-(s<rsub|r>*v<rsub|r><rsup|2>)<rsup|i,j-1/2>=>|<cell|>>|<row|<cell|>|<cell|(s<rsub|r>\<phi\>)<rsup|i,j-1/2>-(s<rsub|r>\<phi\>)<rsup|i,j+1/2>+<with|color|blue|<with|math-font-series|bold|(a*\<phi\>)<rsup|i,j>>>+>|<cell|>>|<row|<cell|>|<cell|(s<rsub|z>*S<rsub|zr>)<rsup|i+1/2,j>-(s<rsub|z>*S<rsub|zr>)<rsup|i-1/2,j>+(s<rsub|r>*S<rsub|rr>)<rsup|i,j+1/2>-(s<rsub|r>*S<rsub|rr>)<rsup|i,j-1/2>-<with|color|blue|<with|math-font-series|bold|(a*S<rsub|\<theta\>\<theta\>>)<rsup|i,j>>>,>|<cell|>>>>
+  </eqnarray*>
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t>(c*v<rsub|z>)<rsup|i,j>+(s<rsub|z>*v<rsup|2><rsub|z>)<rsup|i+1/2,j>-(s<rsub|z>*v<rsup|2><rsub|z>)<rsup|i-1/2,j>+(s<rsub|r>*v<rsub|r><rsup|>*v<rsub|z>)<rsup|i,j+1/2>-(s<rsub|r>*v<rsub|r><rsup|>*v<rsub|z>)<rsup|i,j-1/2>=>|<cell|>>|<row|<cell|>|<cell|(s<rsub|z>\<phi\>)<rsup|i-1/2,j>-(s<rsub|z>\<phi\>)<rsup|i+1/2,j>+>|<cell|>>|<row|<cell|>|<cell|(s<rsub|z>*S<rsub|zz>)<rsup|i+1/2,j>-(s<rsub|z>*S<rsub|zz>)<rsup|i-1/2,j>+(s<rsub|r>*S<rsub|zr>)<rsup|i,j+1/2>-(s<rsub|r>*S<rsub|zr>)<rsup|i,j-1/2>>|<cell|>>>>
+  </eqnarray*>
+
+  <\equation*>
+    (s<rsub|z>*v<rsub|z>)<rsup|i+1/2,j>-(s<rsub|z>*v<rsub|z>)<rsup|i-1/2,j>+(s<rsub|r>*v<rsub|r>)<rsup|i,j+1/2>-(s<rsub|r>*v<rsub|r>)<rsup|i,j-1/2>=0,
+  </equation*>
+
+  where only the bold terms differ from the discretisation of the N--S
+  equations in Cartesian coordinates in \ two dimensions.
+
+  The projection method relies on a decomposition of the velocity as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|v<rsup|i,j><rsub|r>>|<cell|=>|<cell|(v<rsub|r><rsup|\<star\>>)<rsup|i,j>+<frac|\<Delta\>t|c<rsup|i,j>><left|[>(s<rsub|r>\<phi\>)<rsup|i,j-1/2>-(s<rsub|r>\<phi\>)<rsup|i,j+1/2>+<with|color|blue|<with|math-font-series|bold|(a*\<phi\>)<rsup|i,j>>><right|]>,>>|<row|<cell|v<rsup|i,j><rsub|z>>|<cell|=>|<cell|(v<rsub|z><rsup|\<star\>>)<rsup|i,j>+<frac|\<Delta\>t|c<rsup|i,j>><left|[>(s<rsub|z>\<phi\>)<rsup|i-1/2,j>-(s<rsub|z>\<phi\>)<rsup|i+1/2,j><right|]>,>>>>
+  </eqnarray*>
+
+  wich leads to the Poisson-like equation
+
+  <\equation*>
+    <frac|1|\<Delta\>t>*<left|[>s<rsup|i+1/2,j><rsub|z>**(v<rsub|z><rsup|\<star\>>)<rsup|i+1/2,j>-s<rsup|i-1/2,j><rsub|z>*(v<rsub|z><rsup|\<star\>>)<rsup|i-1/2,j>+s<rsup|i,j+1/2><rsub|r>*(v<rsub|r><rsup|\<star\>>)<rsup|i,j+1/2>-s<rsup|i,j-1/2><rsub|r>*(v<rsub|r><rsup|\<star\>>)<rsup|i,j-1/2><right|]>+\<phi\><rsup|i,j>*<left|(>s<rsup|i,j><rsub|z>*<left|[>(s<rsub|z>/c)<rsup|i+1/2,j>+(s<rsub|z>/c)<rsup|i-1/2,j><right|]>+s<rsup|i,j><rsub|r>*<left|[>(s<rsub|r>/c)<rsup|i,j+1/2>+(s<rsub|r>/c)<rsup|i,j-1/2><right|]><right|)>+s<rsup|i,j+1/2><rsub|r>*(a*\<phi\>)<rsup|i,j+1/2>-s<rsup|i,j-1/2><rsub|r>*(a*\<phi\>)<rsup|i,j-1/2>-(s<rsub|z>/c)<rsup|i+1/2,j>*(s<rsub|z>\<phi\>)<rsup|i+1,j>-(s<rsub|z>/c)<rsup|i-1/2,j>*(s<rsub|z>\<phi\>)<rsup|i-1,j>-(s<rsub|r>/c)<rsup|i,j+1/2>*(s<rsub|r>\<phi\>)<rsup|i,j+1>-(s<rsub|r>/c)<rsup|i,j-1/2>*(s<rsub|r>\<phi\>)<rsup|i,j-1>=0.
+  </equation*>
+
+  This looks complicated though... What about just splitting the velocity as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|v<rsup|i,j><rsub|r>>|<cell|=>|<cell|(v<rsub|r><rsup|\<star\>>)<rsup|i,j>+\<Delta\>t*<left|(>\<phi\><rsup|i,j-1/2>-\<phi\><rsup|i,j+1/2><right|)>,>>|<row|<cell|v<rsup|i,j><rsub|z>>|<cell|=>|<cell|(v<rsub|z><rsup|\<star\>>)<rsup|i,j>+\<Delta\>t*<left|(>\<phi\><rsup|i-1/2,j>-\<phi\><rsup|i+1/2,j><right|)>,>>>>
+  </eqnarray*>
+
+  which is still consistent with equations (<reference|momr>) and
+  (<reference|momz>). This gives
+
+  <\equation*>
+    <frac|1|\<Delta\>t>*<left|[>s<rsup|i+1/2,j><rsub|z>**(v<rsub|z><rsup|\<star\>>)<rsup|i+1/2,j>-s<rsup|i-1/2,j><rsub|z>*(v<rsub|z><rsup|\<star\>>)<rsup|i-1/2,j>+s<rsup|i,j+1/2><rsub|r>*(v<rsub|r><rsup|\<star\>>)<rsup|i,j+1/2>-s<rsup|i,j-1/2><rsub|r>*(v<rsub|r><rsup|\<star\>>)<rsup|i,j-1/2><right|]>+\<phi\><rsup|i,j>*(s<rsup|i+1/2,j><rsub|z>+s<rsup|i-1/2,j><rsub|z>+s<rsup|i,j+1/2><rsub|r>+s<rsup|i,j-1/2><rsub|r>)-s<rsub|z><rsup|i+1/2,j>*\<phi\><rsup|i+1,j>-s<rsub|z><rsup|i-1/2,j>*\<phi\><rsup|i-1,j>-s<rsub|r><rsup|i,j+1/2>*\<phi\><rsup|i,j+1>-s<rsub|r><rsup|i,j-1/2>*\<phi\><rsup|i,j-1>=0,
+  </equation*>
+
+  together with
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c<rsup|i,j>*<frac|(v<rsub|r><rsup|\<star\>>)<rsup|i,j>-v<rsup|i,j><rsub|r>|\<Delta\>t>+(s<rsub|z>*v<rsub|r>*v<rsub|z>)<rsup|i+1/2,j>-(s<rsub|z>*v<rsub|r>*v<rsub|z>)<rsup|i-1/2,j>+(s<rsub|r>*v<rsub|r><rsup|2>)<rsup|i,j+1/2>-(s<rsub|r>*v<rsub|r><rsup|2>)<rsup|i,j-1/2>=>|<cell|>>|<row|<cell|>|<cell|(s<rsub|z>*S<rsub|zr>)<rsup|i+1/2,j>-(s<rsub|z>*S<rsub|zr>)<rsup|i-1/2,j>+(s<rsub|r>*S<rsub|rr>)<rsup|i,j+1/2>-(s<rsub|r>*S<rsub|rr>)<rsup|i,j-1/2>-<with|color|blue|<with|math-font-series|bold|(a*S<rsub|\<theta\>\<theta\>>)<rsup|i,j>>>,>|<cell|>>>>
+  </eqnarray*>
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c<rsup|i,j>*<frac|(v<rsub|z><rsup|\<star\>>)<rsup|i,j>-v<rsup|i,j><rsub|z>|\<Delta\>t>+(s<rsub|z>*v<rsup|2><rsub|z>)<rsup|i+1/2,j>-(s<rsub|z>*v<rsup|2><rsub|z>)<rsup|i-1/2,j>+(s<rsub|r>*v<rsub|r><rsup|>*v<rsub|z>)<rsup|i,j+1/2>-(s<rsub|r>*v<rsub|r><rsup|>*v<rsub|z>)<rsup|i,j-1/2>=>|<cell|>>|<row|<cell|>|<cell|(s<rsub|z>*S<rsub|zz>)<rsup|i+1/2,j>-(s<rsub|z>*S<rsub|zz>)<rsup|i-1/2,j>+(s<rsub|r>*S<rsub|zr>)<rsup|i,j+1/2>-(s<rsub|r>*S<rsub|zr>)<rsup|i,j-1/2>.>|<cell|>>>>
+  </eqnarray*>
+
+  <subsection|Advection term>
+
+  <\equation*>
+    u<rsup|n+1/2><rsub|d>=u<rsup|n>+<frac|h|2>*\<partial\><rsub|d>u<rsup|n>+<frac|\<Delta\>t|2>*\<partial\><rsub|t>u<rsup|n>+\<cal-O\>(h<rsup|2>,\<Delta\>t<rsup|2>),
+  </equation*>
+
+  using equations (<reference|momr>), (<reference|momz>) and
+  (<reference|continuity>) then gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|v<rsup|n+1/2><rsub|r>=v<rsup|n><rsub|r>+<frac|1|2>*(h*-v<rsub|r>*\<Delta\>t)*\<partial\><rsub|r>v<rsub|r><rsup|n>+<frac|\<Delta\>t|2>*(-v<rsup|n><rsub|z>*\<partial\><rsub|z>v<rsup|n><rsub|r*>+src<rsup|n>),>|<cell|>|<cell|>>|<row|<cell|v<rsup|n+1/2><rsub|z>=v<rsub|z><rsup|n>+<frac|1|2>*(h-v<rsub|z>*\<Delta\>t)*\<partial\><rsub|z>v<rsub|z><rsup|n>+<frac|\<Delta\>t|2>*<left|(>-v<rsup|n><rsub|r>*\<partial\><rsub|r>v<rsup|n><rsub|z>+src<rsup|n><right|)>,>|<cell|>|<cell|>>>>
+  </eqnarray*>
+
+  which is the same as in the two-dimensional case.
+
+  <subsection|Implicit diffusion>
+
+  <subsubsection|Original implicit diffusion>
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c*<frac|v<rsup|\<star\>>-v<rsup|n>|\<Delta\>t>-\<beta\>*\<nabla\>s*S<rsup|\<star\>><rsup|*>=src<rsup|n+1/2>+(1-\<beta\>)*\<nabla\>s*S<rsup|n>>|<cell|>>>>
+  </eqnarray*>
+
+  which can be rewritten
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c*v<rsup|\<star\>>-\<nabla\><wide|s|^>*S<rsup|\<star\>>=c*v<rsup|n>+\<Delta\>t*src<rsup|n+1/2>+<frac|1-\<beta\>|\<beta\>>*\<nabla\><wide|s|^>*S<rsup|n>,>|<cell|>>>>
+  </eqnarray*>
+
+  with
+
+  <\equation*>
+    <wide|s|^>\<equiv\>\<beta\>*\<Delta\>t*s.
+  </equation*>
+
+  This finally gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|v<rsup|\<star\>>-<frac|1|c>\<nabla\><wide|s|^>*S<rsup|\<star\>>=v<rsup|n>+\<Delta\>t*<wide|src|^><rsup|n+1/2>+<frac|<wide|\<beta\>|^>|c>*\<nabla\><wide|s|^>*S<rsup|n>,>|<cell|>>>>
+  </eqnarray*>
+
+  with <math|><with|mode|math|<wide|\<beta\>|^>\<equiv\>(1-\<beta\>)/\<beta\>>.
+
+  <subsubsection|Axisymmetric version>
+
+  To account for the axisymmetric term this needs to be rewritten
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c*<frac|v<rsup|\<star\>>-v<rsup|n>|\<Delta\>t>-\<beta\>*\<nabla\>s*S<rsup|\<star\>>+\<beta\>*a*2*\<nu\>*<frac|v<rsup|\<star\>>|r>=src<rsup|n+1/2>+(1-\<beta\>)*\<nabla\>s*S<rsup|n>-(1-\<beta\>)*a*2*\<nu\>*<frac|v<rsup|n>|r>>|<cell|>>>>
+  </eqnarray*>
+
+  which can be rewritten
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|c*v<rsup|\<star\>>*-\<nabla\><wide|s|^>*S<rsup|\<star\>>+2*\<beta\>*\<Delta\>t*a*\<nu\>*<frac|v<rsup|\<star\>>|r>=c*v<rsup|n>+\<Delta\>t*src<rsup|n+1/2>+<frac|1-\<beta\>|\<beta\>>*\<nabla\><wide|s|^>*S<rsup|n>-2*(1-\<beta\>)*\<Delta\>t*a*\<nu\>*<frac|v<rsup|n>|r>>|<cell|>>>>
+  </eqnarray*>
+
+  this finally gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|v<rsup|\<star\>>*-<frac|1|c>*\<nabla\><wide|s|^>*S<rsup|\<star\>>+2*\<beta\>*\<Delta\>t*\<nu\>*<frac|v<rsup|\<star\>>|r<rsup|2>>=v<rsup|n>+\<Delta\>t*<wide|src|^><rsup|n+1/2>+<frac|1-\<beta\>|\<beta\>*c>*\<nabla\><wide|s|^>*S<rsup|n>-2*(1-\<beta\>)*\<Delta\>t*\<nu\>*<frac|v<rsup|n>|r<rsup|2>>>|<cell|>>>>
+  </eqnarray*>
+
+  Posing <math|d\<equiv\>2*\<beta\>*\<Delta\>t*\<nu\>/r<rsup|2>> then gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|v<rsup|\<star\>>*(1+d)-<frac|1|c>*\<nabla\><wide|s|^>*S<rsup|\<star\>>=v<rsup|n>*<left|(>1-<wide|\<beta\>*|^>*d<right|)>+\<Delta\>t*<wide|src|^><rsup|n+1/2>+<frac|<wide|\<beta\>*|^>*|c>*\<nabla\><wide|s|^>*S<rsup|n>.>|<cell|>>>>
+  </eqnarray*>
+</body>
+
+<\references>
+  <\collection>
+    <associate|auto-1|<tuple|1|?>>
+    <associate|auto-2|<tuple|2|?>>
+    <associate|auto-3|<tuple|2.1|?>>
+    <associate|auto-4|<tuple|2.2|?>>
+    <associate|auto-5|<tuple|3|?>>
+    <associate|continuity|<tuple|3|?>>
+    <associate|momr|<tuple|1|?>>
+    <associate|momz|<tuple|2|?>>
+    <associate|mon|<tuple|?|?>>
+  </collection>
+</references>
+
+<\auxiliary>
+  <\collection>
+    <\associate|toc>
+      <with|par-left|<quote|3fn>|1<space|2spc>Advection term
+      <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-1>>
+    </associate>
+  </collection>
+</auxiliary>
\ No newline at end of file
diff --git a/doc/figures/corner.fig b/doc/figures/corner.fig
new file mode 100644
index 0000000..9c7b0fd
--- /dev/null
+++ b/doc/figures/corner.fig
@@ -0,0 +1,84 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3300 5400 3300 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 5400 3300 5400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3300 3000 5700 3000 5700 5400 3300 5400 3300 3000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 900 5400 3300 5400 3300 7800 900 7800 900 5400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 900 3000 3300 3000 3300 5400 900 5400 900 3000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3300 5400 5700 5400 5700 7800 3300 7800 3300 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 5400 2100 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 6600 3300 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2700 6600 2700 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 7200 3300 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 6000 2100 6000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1500 5400 1500 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 3000 2100 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 4200 3300 4200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4500 5400 4500 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3300 6600 5700 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1500 6600 1500 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 7200 2100 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 6600 1200 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 7200 1200 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 7500 1500 7500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 900 6900 1500 6900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1500 7500 2100 7500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1800 7200 1800 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1350 7200 1350 7500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 7350 1500 7350
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 1800 6600 1800 7200
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 1500 6900 2100 6900
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 17
+	 2700 5400 2700 5475 2700 5550 2700 5700 2700 5775 2700 5850
+	 2700 6000 2700 6075 2700 6150 2700 6225 2700 6300 2700 6375
+	 2700 6450 2700 6525 2700 6600 2700 6675 2700 6600
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 2100 6000 3300 6000
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 4500 3000 4500 5400
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 3300 4200 5700 4200
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 4.00 60.00 60.00
+	 1425 7275 1650 7050
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 4.00 60.00 60.00
+	 1950 6750 2400 6300
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 4.00 60.00 60.00
+	 3000 5700 3900 4800
diff --git a/doc/figures/cubed.fig b/doc/figures/cubed.fig
new file mode 100644
index 0000000..4354253
--- /dev/null
+++ b/doc/figures/cubed.fig
@@ -0,0 +1,76 @@
+#FIG 3.2  Produced by xfig version 3.2.5
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 2812.500 5737.500 2025 5625 2250 5175 2700 4950
+	1 1 1.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 4162.500 4387.500 3375 4275 3600 3825 4050 3600
+	1 1 1.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 5512.500 3037.500 4725 2925 4950 2475 5400 2250
+	1 1 1.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 5738.000 4613.000 6525 4725 6300 5175 5850 5400
+	1 1 1.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 4388.000 5963.000 5175 6075 4950 6525 4500 6750
+	1 1 1.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 0 0 1 0 3038.000 7313.000 3825 7425 3600 7875 3150 8100
+	1 1 1.00 120.00 240.00
+6 1575 5850 2925 7200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 1575 5850 2925 5850 2925 7200 1575 7200 1575 5850
+4 1 0 50 -1 0 28 0.0000 4 315 240 2250 6660 1\001
+-6
+6 5625 3150 6975 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5625 3150 6975 3150 6975 4500 5625 4500 5625 3150
+4 1 0 50 -1 0 28 0.0000 4 315 240 6300 3960 6\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2925 5850 4275 5850 4275 7200 2925 7200 2925 5850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2925 4500 4275 4500 4275 5850 2925 5850 2925 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4275 3150 5625 3150 5625 4500 4275 4500 4275 3150
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4275 4500 5625 4500 5625 5850 4275 5850 4275 4500
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 2925 7425 2925 8595
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 4275 7425 4275 8595
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 5625 6075 5625 8595
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 6975 4725 6975 8595
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 4500 7200 8325 7200
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 5850 5850 8325 5850
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 7200 4500 8325 4500
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 7200 3150 8325 3150
+2 2 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
+	 1575 7200 2925 7200 2925 8550 1575 8550 1575 7200
+2 2 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
+	 5625 1800 6975 1800 6975 3150 5625 3150 5625 1800
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
+	 1575 7425 1575 8595
+4 1 0 50 -1 0 28 0.0000 4 315 240 3600 6660 2\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 3600 5310 3\001
+4 1 0 50 -1 0 28 0.0000 4 330 240 4950 3960 5\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 4950 5310 4\001
+4 1 0 50 -1 0 28 0.0000 4 315 390 1575 9225 -1\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 2925 9225 1\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 4275 9225 3\001
+4 1 0 50 -1 0 28 0.0000 4 330 240 5625 9225 5\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 6975 9225 7\001
+4 1 0 50 -1 0 28 0.0000 4 315 390 8775 7425 -1\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 8775 6075 1\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 8775 4725 3\001
+4 1 0 50 -1 0 28 0.0000 4 330 240 8775 3375 5\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 2250 8010 6\001
+4 1 0 50 -1 0 28 0.0000 4 315 240 6300 2610 1\001
diff --git a/doc/figures/gse.tm b/doc/figures/gse.tm
new file mode 100644
index 0000000..aea0ccd
--- /dev/null
+++ b/doc/figures/gse.tm
@@ -0,0 +1,252 @@
+<TeXmacs|1.0.6.11>
+
+<style|<tuple|article|maxima>>
+
+<\body>
+  <section|GSE alleviation using spatial filtering (or is it diffusion?)>
+
+  Following Tolman, 2002, Appendix A, the filtered value is defined as
+
+  <\equation>
+    F<rsub|avg>(\<b-x\>)=<frac|1|3>*F(\<b-x\>)+<frac|1|6>*<big|sum><rsup|4><rsub|n=1>F(\<b-x\>+\<b-r\><rsub|n>),<label|avg>
+  </equation>
+
+  with
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<b-r\><rsub|1>>|<cell|=>|<cell|\<b-s\>+\<b-n\>,>>|<row|<cell|\<b-r\><rsub|2>>|<cell|=>|<cell|-\<b-s\>+\<b-n\>,>>|<row|<cell|\<b-r\><rsub|3>>|<cell|=>|<cell|-\<b-s\>-\<b-n\>,>>|<row|<cell|\<b-r\><rsub|4>>|<cell|=>|<cell|\<b-s\>-\<b-n\>>>>>
+  </eqnarray*>
+
+  and
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<with|math-font-series|bold|s>>|<cell|=>|<cell|\<alpha\>*<matrix|<tformat|<table|<row|<cell|cos
+    \<theta\>>>|<row|<cell|sin \<theta\>>>>>>,>>|<row|<cell|\<b-n\>>|<cell|=>|<cell|\<beta\>*<matrix|<tformat|<table|<row|<cell|-sin
+    \<theta\>>>|<row|<cell|cos \<theta\>>>>>>.>>>>
+  </eqnarray*>
+
+  To third-order the Taylor expansion of <math|F> can be written
+
+  <\equation>
+    F(\<b-x\>+\<b-r\>)=F(\<b-x\>)+\<b-r\>*\<b-F\><rprime|'>(\<b-x\>)+<frac|1|2>*\<b-r\><rsup|T>*\<b-F\><rprime|''>(\<b-x\>)*\<b-r\>,<label|taylor>
+  </equation>
+
+  with the gradient <math|\<b-F\><rprime|'>> and Hessian
+  <math|\<b-F\><rprime|''>> given by
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<with|mode|text|<math|\<b-F\><rprime|'>>>>|<cell|\<equiv\>>|<cell|<matrix|<tformat|<table|<row|<cell|<frac|\<partial\>F|\<partial\>x>>>|<row|<cell|<frac|\<partial\>F|\<partial\>y>>>>>>,>>|<row|<cell|<with|mode|text|<math|\<b-F\><rprime|''>>>>|<cell|\<equiv\>>|<cell|<matrix|<tformat|<table|<row|<cell|<frac|\<partial\><rsup|2>F|\<partial\>x<rsup|2>>>|<cell|<frac|\<partial\><rsup|2>F|\<partial\>x\<partial\>y>>>|<row|<cell|<frac|\<partial\><rsup|2>F|\<partial\>x\<partial\>y>>|<cell|<frac|\<partial\><rsup|2>F|\<partial\>y<rsup|2>>>>>>>.>>>>
+  </eqnarray*>
+
+  Using (<reference|taylor>) in (<reference|avg>) gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|F<rsub|avg>(\<b-x\>)>|<cell|=>|<cell|<frac|1|3>*F(\<b-x\>)+<frac|1|6>*<big|sum><rsup|4><rsub|n=1>F(\<b-x\>)+\<b-r\><rsub|n>*\<b-F\><rprime|'>(\<b-x\>)+<frac|1|2>*\<b-r\><rsub|n><rsup|T>*\<b-F\><rprime|''>(\<b-x\>)*\<b-r\><rsub|n>>>|<row|<cell|>|<cell|=>|<cell|F(\<b-x\>)+<frac|1|6>*\<b-F\><rprime|'>(\<b-x\>)*<big|sum><rsup|4><rsub|n=1>\<b-r\><rsub|n>+<frac|1|12>*<big|sum><rsup|4><rsub|n=1>\<b-r\><rsub|n><rsup|T>*\<b-F\><rprime|''>(\<b-x\>)*\<b-r\><rsub|n>>>|<row|<cell|>|<cell|=>|<cell|F(\<b-x\>)+<frac|1|12>*<big|sum><rsup|4><rsub|n=1>\<b-r\><rsub|n><rsup|T>*\<b-F\><rprime|''>(\<b-x\>)*\<b-r\><rsub|n>>>>>
+  </eqnarray*>
+
+  I am lazy so I use Maxima to obtain the simplified form
+
+  <with|prog-language|maxima|prog-session|default|<\session>
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>1)
+    <with|color|black|>>>
+      s:matrix([alpha*cos(theta)],[alpha*sin(theta)]);
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o1>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|\<alpha\>*cos
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|\<alpha\>*sin
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>2)
+    <with|color|black|>>>
+      n:matrix([-beta*sin(theta)],[beta*cos(theta)]);
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o2>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|-\<beta\>*sin
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|\<beta\>*cos
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>3)
+    <with|color|black|>>>
+      F:matrix( [Fxx,Fxy], [Fxy,Fyy] );
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o3>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|<with|math-font-family|rm|Fxx>>|<cell|<with|math-font-family|rm|Fxy>>>|<row|<cell|<with|math-font-family|rm|Fxy>>|<cell|<with|math-font-family|rm|Fyy>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>4)
+    <with|color|black|>>>
+      r1: s+n;
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o4>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|\<alpha\>*cos
+      <left|(>\<vartheta\><right|)>-\<beta\>*sin
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|\<alpha\>*sin
+      <left|(>\<vartheta\><right|)>+\<beta\>*cos
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>5)
+    <with|color|black|>>>
+      r2: -s+n;
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o5>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|-\<beta\>*sin
+      <left|(>\<vartheta\><right|)>-\<alpha\>*cos
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|\<beta\>*cos
+      <left|(>\<vartheta\><right|)>-\<alpha\>*sin
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>6)
+    <with|color|black|>>>
+      r3: -s-n;
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o6>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|\<beta\>*sin
+      <left|(>\<vartheta\><right|)>-\<alpha\>*cos
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|-\<alpha\>*sin
+      <left|(>\<vartheta\><right|)>-\<beta\>*cos
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>7)
+    <with|color|black|>>>
+      r4: s-n;
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o10>)
+      <with|color|black|>><left|(><tabular*|<tformat|<table|<row|<cell|\<beta\>*sin
+      <left|(>\<vartheta\><right|)>+\<alpha\>*cos
+      <left|(>\<vartheta\><right|)>>>|<row|<cell|\<alpha\>*sin
+      <left|(>\<vartheta\><right|)>-\<beta\>*cos
+      <left|(>\<vartheta\><right|)>>>>>><right|)>>
+    </output>
+
+    <\input|<with|color|red|(<with|math-font-family|rm|%i>11)
+    <with|color|black|>>>
+      ratsimp(transpose(r1).F.r1+transpose(r2).F.r2+transpose(r3).F.r3+transpose(r4).F.r4);
+    </input>
+
+    <\output>
+      <with|mode|math|math-display|true|<with|mode|text|font-family|tt|color|red|(<with|math-font-family|rm|%o12>)
+      <with|color|black|>><left|(>4*\<alpha\><rsup|2>*<with|math-font-family|rm|Fyy>+4*\<beta\><rsup|2>*<with|math-font-family|rm|Fxx><right|)>*sin
+      <left|(>\<vartheta\><right|)><rsup|2>+<left|(>8*\<alpha\><rsup|2>-8*\<beta\><rsup|2><right|)>*<with|math-font-family|rm|Fxy>*cos
+      <left|(>\<vartheta\><right|)>*sin <left|(>\<vartheta\><right|)>+<left|(>4*\<beta\><rsup|2>*<with|math-font-family|rm|Fyy>+4*\<alpha\><rsup|2>*<with|math-font-family|rm|Fxx><right|)>*cos
+      <left|(>\<vartheta\><right|)><rsup|2>>
+    </output>
+  </session>>
+
+  We get
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|F<rsub|avg>(\<b-x\>)>|<cell|=>|<cell|F(\<b-x\>)+>>|<row|<cell|>|<cell|>|<cell|<frac|1|3>**(\<alpha\><rsup|2>*cos<rsup|2>
+    \<theta\>+\<beta\><rsup|2>*sin<rsup|2> \<theta\>)*F<rsub|x
+    x>*+>>|<row|<cell|>|<cell|>|<cell|<frac|1|3>**(\<alpha\><rsup|2>*sin<rsup|2>
+    \<theta\>+\<beta\><rsup|2>*cos<rsup|2> \<theta\>)*F<rsub|y
+    y>+>>|<row|<cell|>|<cell|>|<cell|<frac|2|3>
+    (\<alpha\><rsup|2>-\<beta\><rsup|2>)*cos \<theta\>*sin \<theta\>*F<rsub|x
+    y>,>>>>
+  </eqnarray*>
+
+  which can be rewritten
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<frac|F<rsub|avg>(\<b-x\>)-F(\<b-x\>)|\<Delta\>t>>|<cell|=>|<cell|D<rsub|x
+    x>*F<rsub|x x>+D<rsub|y y>*F<rsub|y y>+2*D<rsub|x y>*F<rsub|x y>,>>>>
+  </eqnarray*>
+
+  with
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|D<rsub|x*x>>|<cell|\<equiv\>>|<cell|D<rsub|s*s>*cos<rsup|2>
+    \<theta\>+D<rsub|n*n>*sin<rsup|2> \<theta\>,>>|<row|<cell|D<rsub|y*y>>|<cell|\<equiv\>>|<cell|D<rsub|s*s>*sin<rsup|2>
+    \<theta\>+D<rsub|n*n>*cos<rsup|2> \<theta\>,>>|<row|<cell|D<rsub|x*y>>|<cell|\<equiv\>>|<cell|(D<rsub|s*s>-D<rsub|n*n>)*cos
+    \<theta\>*sin \<theta\>,>>>>
+  </eqnarray*>
+
+  and
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|D<rsub|s*s>>|<cell|\<equiv\>>|<cell|<frac|\<alpha\><rsup|2>|3*\<Delta\>t>,>>|<row|<cell|D<rsub|n*n>>|<cell|\<equiv\>>|<cell|<frac|\<beta\><rsup|2>|3*\<Delta\>t>.>>>>
+  </eqnarray*>
+
+  This means that to third-order accuracy the spatial-filtering scheme of
+  Tolman is formally equivalent to a first-order time discretisation of the
+  diffusion equation of Booij and Holthuijsen, 1987. Furthermore Tolman takes
+  <math|\<alpha\>> and <math|\<beta\>> as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<alpha\>>|<cell|\<equiv\>>|<cell|\<alpha\><rsub|s>*\<Delta\>c<rsub|g>*\<Delta\>t,>>|<row|<cell|\<beta\>>|<cell|\<equiv\>>|<cell|\<alpha\><rsub|n>*c<rsub|g>*\<Delta\>\<theta\>*\<Delta\>t,>>>>
+  </eqnarray*>
+
+  with <math|\<Delta\>c<rsub|g>\<equiv\>><with|mode|math|(\<gamma\>-\<gamma\><rsup|-1>)*c<rsub|g>/2>,
+  whereas Booij and Holthuijsen take
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<wide|D|^><rsub|s*s>>|<cell|\<equiv\>>|<cell|<frac|1|12>*(\<Delta\>c<rsub|g>)<rsup|2>*T<rsub|s>,>>|<row|<cell|<wide|D|^><rsub|n*n>>|<cell|\<equiv\>>|<cell|<frac|1|12>*(c<rsub|g>*\<Delta\>\<theta\>)<rsup|2>*T<rsub|s>.>>>>
+  </eqnarray*>
+
+  The two schemes are actually equivalent when <math|D<rsub|s*s>>,
+  <math|D<rsub|n*n>> are identical to <math|<wide|D|^><rsub|s*s>>,
+  <math|<wide|D|^><rsub|n*n>> which gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|T<rsub|s>>|<cell|=>|<cell|4*\<alpha\><rsup|2><rsub|s>*\<Delta\>t,>>|<row|<cell|\<alpha\><rsub|n>>|<cell|=>|<cell|\<alpha\><rsub|s>.>>>>
+  </eqnarray*>
+
+  This is obviously a much smaller value for <math|T<rsub|s>> than the 4 days
+  used in Tolman 2002 and I am not sure I understand where this discrepancy
+  comes from... The stability criterion for the explicit diffusion scheme
+  then becomes
+
+  <\equation*>
+    \<Delta\>t\<less\><frac|(\<Delta\>x)<rsup|2>|(c<rsub|g>*\<Delta\>\<theta\>)<rsup|2>*4*\<alpha\><rsup|2><rsub|s>*\<Delta\>t>
+  </equation*>
+
+  which simplifies as
+
+  <\equation*>
+    \<Delta\>t\<less\><frac|\<Delta\>x|2*\<alpha\><rsub|s>*c<rsub|g>*\<Delta\>\<theta\>>
+  </equation*>
+
+  which is the standard CFL stability criterion with a CFL number of
+  <math|(2*\<alpha\><rsub|s>*\<Delta\>\<theta\>)<rsup|-1>>. For 24 wave
+  directions this number is larger than one for
+  <math|\<alpha\><rsub|s>\<lesssim\>2>, which means that this scheme does not
+  restrict the timestep if wave advection is resolved using an explicit
+  scheme (as is usually the case).
+</body>
+
+<\references>
+  <\collection>
+    <associate|auto-1|<tuple|1|1>>
+    <associate|avg|<tuple|1|1>>
+    <associate|taylor|<tuple|2|1>>
+  </collection>
+</references>
+
+<\auxiliary>
+  <\collection>
+    <\associate|toc>
+      <vspace*|1fn><with|font-series|<quote|bold>|math-font-series|<quote|bold>|1<space|2spc>GSE
+      alleviation using spatial filtering (or is it diffusion?)>
+      <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-1><vspace|0.5fn>
+    </associate>
+  </collection>
+</auxiliary>
\ No newline at end of file
diff --git a/doc/figures/indices.fig b/doc/figures/indices.fig
new file mode 100644
index 0000000..da1edbe
--- /dev/null
+++ b/doc/figures/indices.fig
@@ -0,0 +1,130 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 2250 2250 2550 2550
+1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 2400 2400 106 106 2400 2400 2475 2475
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2400 2400 46 46 2400 2400 2446 2400
+-6
+6 1200 1200 3600 3600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1200 1200 3600 1200 3600 3600 1200 3600 1200 1200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2400 1200 2400 3600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2400 3600 2400
+-6
+6 5025 225 9375 4575
+6 6000 1200 8400 3600
+6 6000 1200 8400 3600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6000 1200 8400 1200 8400 3600 6000 3600 6000 1200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 1200 7200 3600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 2400 8400 2400
+-6
+6 7050 2250 7350 2550
+1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 7200 2400 106 106 7200 2400 7275 2475
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 7200 2400 46 46 7200 2400 7246 2400
+-6
+4 0 0 50 0 0 18 0.0000 4 195 135 7725 1875 0\001
+4 0 0 50 0 0 18 0.0000 4 195 135 6525 3075 6\001
+4 0 0 50 0 0 18 0.0000 4 195 135 7725 3075 2\001
+4 0 0 50 0 0 18 0.0000 4 195 135 6525 1875 4\001
+4 0 0 50 0 0 18 0.0000 4 195 135 7275 2250 1\001
+-6
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 8700 2400 9300 2400
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 5700 2400 5100 2400
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 7200 900 7200 300
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 7200 3900 7200 4500
+4 0 0 50 0 0 18 0.0000 4 195 135 5475 2775 5\001
+4 0 0 50 0 0 18 0.0000 4 195 135 7425 4200 3\001
+4 0 0 50 0 0 18 0.0000 4 195 135 8850 2775 4\001
+4 0 0 50 0 0 18 0.0000 4 195 135 7425 825 2\001
+4 0 0 50 0 0 14 0.0000 4 150 105 6675 2025 5\001
+4 0 0 50 0 0 14 0.0000 4 150 105 7875 2025 1\001
+4 0 0 50 0 0 14 0.0000 4 150 105 6675 3225 7\001
+4 0 0 50 0 0 14 0.0000 4 150 105 7875 3225 3\001
+-6
+6 1200 6000 3600 8400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 6000 3600 8400 1200 8400 1200 6000 3600 6000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 7200 1200 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2400 6000 2400 8400
+-6
+6 2250 7050 2550 7350
+1 3 0 1 0 7 50 0 -1 0.000 1 4.7124 2400 7200 106 106 2400 7200 2325 7275
+1 3 0 1 0 0 50 0 20 0.000 1 4.7124 2400 7200 46 46 2400 7200 2400 7246
+-6
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 3900 2400 4500 2400
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 900 2400 300 2400
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 2400 900 2400 300
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 2400 3900 2400 4500
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 2400 8700 2400 9300
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 2400 5700 2400 5100
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 3900 7200 4500 7200
+2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	2 1 1.00 180.00 240.00
+	 900 7200 300 7200
+4 0 0 50 0 0 18 0.0000 4 195 135 1725 1875 0\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2925 1875 1\001
+4 0 0 50 0 0 18 0.0000 4 195 135 1725 3075 2\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2925 3075 3\001
+4 0 0 50 0 0 18 0.0000 4 195 135 675 2775 1\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2625 4200 3\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2625 825 2\001
+4 0 0 50 0 0 18 0.0000 4 195 135 4050 2775 0\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2475 2250 4\001
+4 0 0 50 0 0 14 0.0000 4 150 105 1875 2025 4\001
+4 0 0 50 0 0 14 0.0000 4 150 105 3075 2025 5\001
+4 0 0 50 0 0 14 0.0000 4 150 105 3075 3225 7\001
+4 0 0 50 0 0 14 0.0000 4 150 105 1875 3225 6\001
+4 0 0 50 0 0 18 0.0000 4 195 135 1725 6675 4\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2925 6675 5\001
+4 0 0 50 0 0 18 0.0000 4 195 135 1725 7875 0\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2925 7875 1\001
+4 0 0 50 0 0 14 0.0000 4 150 105 1875 6825 6\001
+4 0 0 50 0 0 14 0.0000 4 150 105 3075 6825 7\001
+4 0 0 50 0 0 14 0.0000 4 150 105 1875 8025 2\001
+4 0 0 50 0 0 14 0.0000 4 150 105 3075 8025 3\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2475 7050 2\001
+4 0 0 50 0 0 18 0.0000 4 195 135 675 7575 1\001
+4 0 0 50 0 0 18 0.0000 4 195 135 4050 7575 0\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2625 5625 5\001
+4 0 0 50 0 0 18 0.0000 4 195 135 2625 9000 4\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 1500 10050 children(3)={2,3,6,7}\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 1500 9750 children(2)={0,1,4,5}\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 1500 0 children(5)={4,5,6,7}\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 1500 -300 children(4)={0,1,2,3}\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 6300 -300 children(0)={1,3,5,7}\001
+4 0 0 50 0 0 14 0.0000 4 195 1830 6300 0 children(1)={0,2,4,6}\001
diff --git a/doc/figures/interpolate_2D.fig b/doc/figures/interpolate_2D.fig
new file mode 100644
index 0000000..1bce0f4
--- /dev/null
+++ b/doc/figures/interpolate_2D.fig
@@ -0,0 +1,212 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+0 32 #404040
+0 33 #808080
+0 34 #c0c0c0
+0 35 #8e8f8e
+0 36 #c0c0c0
+0 37 #808080
+0 38 #8e8f8e
+0 39 #404040
+0 40 #808080
+0 41 #c0c0c0
+0 42 #e0e0e0
+0 43 #c6b797
+0 44 #eff8ff
+0 45 #dccba6
+0 46 #aaaaaa
+0 47 #555555
+0 48 #8e8f8e
+0 49 #404040
+0 50 #808080
+0 51 #c0c0c0
+0 52 #e0e0e0
+0 53 #404040
+0 54 #808080
+0 55 #c0c0c0
+0 56 #e0e0e0
+0 57 #808080
+0 58 #c0c0c0
+0 59 #e0e0e0
+0 60 #404040
+0 61 #808080
+0 62 #c0c0c0
+0 63 #404040
+0 64 #c0c0c0
+0 65 #e0e0e0
+0 66 #404040
+0 67 #808080
+0 68 #c0c0c0
+0 69 #8e8f8e
+0 70 #404040
+0 71 #808080
+0 72 #c0c0c0
+0 73 #e0e0e0
+0 74 #404040
+0 75 #808080
+0 76 #c0c0c0
+0 77 #e0e0e0
+0 78 #404040
+0 79 #808080
+0 80 #c0c0c0
+0 81 #e0e0e0
+0 82 #000079
+0 83 #000079
+0 84 #ff8200
+0 85 #007d00
+0 86 #007d00
+0 87 #0000be
+0 88 #000079
+0 89 #007d00
+0 90 #444444
+0 91 #8e8f8e
+0 92 #444444
+0 93 #8e8f8e
+0 94 #444444
+0 95 #8e8f8e
+0 96 #444444
+0 97 #8e8f8e
+0 98 #444444
+0 99 #8e8f8e
+0 100 #444444
+0 101 #8e8f8e
+0 102 #444444
+0 103 #8e8f8e
+0 104 #444444
+0 105 #8e8f8e
+0 106 #444444
+0 107 #8e8f8e
+0 108 #808080
+0 109 #c0c0c0
+0 110 #e0e0e0
+0 111 #8e8e8e
+0 112 #444444
+0 113 #8e8e8e
+0 114 #8e8e8e
+0 115 #8e8e8e
+0 116 #444444
+0 117 #aaaaaa
+0 118 #8e8e8e
+0 119 #444444
+0 120 #aaaaaa
+0 121 #555555
+0 122 #8e8e8e
+0 123 #444444
+0 124 #c0c0c0
+0 125 #e0e0e0
+0 126 #8e8e8e
+0 127 #444444
+0 128 #8e8e8e
+0 129 #444444
+0 130 #8e8e8e
+0 131 #444444
+0 132 #808080
+0 133 #c0c0c0
+0 134 #e0e0e0
+0 135 #c0c0c0
+0 136 #e0e0e0
+6 3075 3075 3225 3225
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3075 3075 3225 3225
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3225 3075 3075 3225
+-6
+6 3450 3000 3750 3300
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3525 3075 3675 3225
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3675 3075 3525 3225
+-6
+6 1650 3000 1950 3300
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1725 3075 1875 3225
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1875 3075 1725 3225
+-6
+6 5250 3000 5550 3300
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 5325 3075 5475 3225
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 5475 3075 5325 3225
+-6
+6 3000 3450 3300 3750
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3075 3525 3225 3675
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3225 3525 3075 3675
+-6
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 3150 2250 75 75 3150 2250 3225 2250
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4050 2250 75 75 4050 2250 4125 2250
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 3150 4950 75 75 3150 4950 3225 4950
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4050 4950 75 75 4050 4950 4125 4950
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2250 3150 75 75 2250 3150 2325 3150
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2250 4050 75 75 2250 4050 2325 4050
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4950 4050 75 75 4950 4050 5025 4050
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4950 3150 75 75 4950 3150 5025 3150
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 2700 2700 4500 2700 4500 4500 2700 4500 2700 2700
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 900 2700 2700 2700 2700 4500 900 4500 900 2700
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 900 900 2700 900 2700 2700 900 2700 900 900
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 2700 900 4500 900 4500 2700 2700 2700 2700 900
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4500 900 6300 900 6300 2700 4500 2700 4500 900
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4500 2700 6300 2700 6300 4500 4500 4500 4500 2700
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 2700 4500 4500 4500 4500 6300 2700 6300 2700 4500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4500 4500 6300 4500 6300 6300 4500 6300 4500 4500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 900 4500 2700 4500 2700 6300 900 6300 900 4500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3525 3525 3675 3525 3675 3675 3525 3675 3525 3525
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 2700 1800 3600 1800 3600 2700 2700 2700 2700 1800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 1800 4500 1800 4500 2700 3600 2700 3600 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2700 5400 4500 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 4500 3600 5400
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 900 3150 6300 3150
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3525 1725 3675 1725 3675 1875 3525 1875 3525 1725
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3525 5325 3675 5325 3675 5475 3525 5475 3525 5325
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1800 2700 1800 4500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1800 3600 2700 3600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 5400 2700 5400 4500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4500 3600 5400 3600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1725 3525 1875 3525 1875 3675 1725 3675 1725 3525
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 5325 3525 5475 3525 5475 3675 5325 3675 5325 3525
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 3150 900 3150 6300
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 900 3600 6300 3600
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+	 3600 900 3600 6300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1725 1725 1875 1725 1875 1875 1725 1875 1725 1725
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 5325 1725 5475 1725 5475 1875 5325 1875 5325 1725
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 5325 5325 5475 5325 5475 5475 5325 5475 5325 5325
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1725 5325 1875 5325 1875 5475 1725 5475 1725 5325
diff --git a/doc/figures/lonlat.fig b/doc/figures/lonlat.fig
new file mode 100644
index 0000000..5fb5b18
--- /dev/null
+++ b/doc/figures/lonlat.fig
@@ -0,0 +1,34 @@
+#FIG 3.2  Produced by xfig version 3.2.5
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+5 1 0 2 0 7 50 -1 -1 0.000 0 1 0 0 3825.000 1117.500 2925 4050 3825 4185 4725 4050
+5 1 0 2 0 7 50 -1 -1 0.000 0 1 0 0 6652.500 5062.500 2925 4050 2790 5085 2925 6075
+5 1 0 2 0 7 50 -1 -1 0.000 0 1 0 0 8452.500 5062.500 4725 4050 4590 5040 4725 6075
+5 1 0 2 0 7 50 -1 -1 0.000 0 1 0 0 3825.000 3150.000 2925 6075 3780 6210 4725 6075
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5971.811 3405.259 5310 3150 5265 3465 5400 3825
+5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5038.176 2797.906 4680 3015 4905 3195 5265 3150
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3
+	 2925 4050 5850 2250 2925 6075
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 2
+	 5850 2250 4725 4050
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 2
+	 5850 2250 4725 6075
+4 0 0 50 -1 1 24 0.0000 4 180 165 3825 3330 r\001
+4 0 0 50 -1 1 24 0.0000 4 180 165 2970 6615 r\001
+4 0 0 50 -1 0 24 0.0000 4 180 555 3240 6615 cos\001
+4 0 0 50 -1 32 24 0.0000 4 285 210 3825 6660 q\001
+4 0 0 50 -1 1 24 0.0000 4 285 210 4140 6615 d\001
+4 0 0 50 -1 1 24 0.0000 4 180 165 1980 5175 r\001
+4 0 0 50 -1 32 24 0.0000 4 285 210 2340 5175 q\001
+4 0 0 50 -1 32 24 0.0000 4 300 225 4635 3465 l\001
+4 0 0 50 -1 32 24 0.0000 4 285 210 5085 4050 q\001
+4 0 0 50 -1 1 24 0.0000 4 285 210 2160 5175 d\001
+4 0 0 50 -1 1 24 0.0000 4 285 210 4455 3465 d\001
+4 0 0 50 -1 1 24 0.0000 4 285 210 4905 4050 d\001
+4 0 0 50 -1 32 24 0.0000 4 300 225 4320 6615 l\001
diff --git a/doc/figures/lonlat.tm b/doc/figures/lonlat.tm
new file mode 100644
index 0000000..2810ff6
--- /dev/null
+++ b/doc/figures/lonlat.tm
@@ -0,0 +1,447 @@
+<TeXmacs|1.0.6.11>
+
+<style|article>
+
+<\body>
+  <doc-data|<doc-title|Derivation of metric coefficients for
+  a<next-line>longitude-latitude coordinate
+  system>|<doc-author-data|<author-name|Stéphane
+  Popinet>>|<doc-date|<date>>|>
+
+  A system of conservation laws of the form
+
+  <\equation>
+    \<partial\><rsub|t><big|int><rsub|\<Omega\>>\<b-U\>*dV+<big|int><rsub|\<partial\>\<Omega\>>\<b-F\>(\<b-U\>)\<cdot\>\<b-n\>*dS=0<label|conservation>
+  </equation>
+
+  is discretised in Gerris as
+
+  <\equation*>
+    h<rsup|2>*c<rsub|i,j>*\<partial\><rsub|t>\<b-U\>+<big|sum><rsub|faces>s<rsub|f>*h*\<b-F\><rsub|f>(\<b-U\>)=0
+  </equation*>
+
+  or
+
+  <\equation>
+    h*c<rsub|i,j>*\<partial\><rsub|t>\<b-U\>+<big|sum><rsub|faces>s<rsub|f>\<b-F\><rsub|f>(\<b-U\>)*=0<label|gerris>
+  </equation>
+
+  with <math|h> the dimensional cell size. The figure below illustrates the
+  lengths of the faces of a surface element in a longitude-latitude
+  coordinate system with <math|\<lambda\>> the longitude and <math|\<theta\>>
+  the latitude.
+
+  <big-figure|<postscript|lonlat.fig|0.3par|||||>|Elementary lengths for a
+  surface element.>
+
+  This leads to the discrete form for (<reference|conservation>)
+
+  <\equation*>
+    r<rsup|2>*cos \<theta\>*d\<theta\>*d\<lambda\>*\<partial\><rsub|t>\<b-U\>+<big|sum><rsub|f<rsub|\<theta\>>>r*d\<theta\>*\<b-F\><rsub|f<rsub|\<theta\>>>(\<b-U\>)+<big|sum><rsub|f<rsub|\<lambda\>>>r*cos
+    \<theta\>*d\<lambda\>*\<b-F\><rsub|f<rsub|\<lambda\>>>(\<b-U\>)=0,
+  </equation*>
+
+  or
+
+  <\equation>
+    r*cos \<theta\>*d\<theta\>*d\<lambda\>*\<partial\><rsub|t>\<b-U\>+<big|sum><rsub|f<rsub|\<theta\>>>d\<theta\>*\<b-F\><rsub|f<rsub|\<theta\>>>(\<b-U\>)+<big|sum><rsub|f<rsub|\<lambda\>>>cos
+    \<theta\>*d\<lambda\>*\<b-F\><rsub|f<rsub|\<lambda\>>>(\<b-U\>)=0.<label|lonlat>
+  </equation>
+
+  Equating the terms with (<reference|gerris>) gives
+
+  <\with|color|blue>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|c<rsub|i,j>>|<cell|\<equiv\>>|<cell|<frac|r|h>*cos
+      \<theta\> *d\<theta\>*d\<lambda\>,>>|<row|<cell|s<rsub|f<rsub|\<theta\>>>>|<cell|\<equiv\>>|<cell|d\<theta\>,>>|<row|<cell|s<rsub|f<rsub|\<lambda\>>>>|<cell|\<equiv\>>|<cell|cos
+      \<theta\>* d\<lambda\>.>>>>
+    </eqnarray*>
+  </with>
+
+  <subsection|Application to the Saint-Venant equations>
+
+  For the Saint-Venant equations <math|\<b-U\>> and <math|\<b-F\>(\<b-U\>)>
+  are given by
+
+  <\equation*>
+    \<b-U\>\<equiv\><matrix|<tformat|<table|<row|<cell|\<phi\>>>|<row|<cell|\<phi\>*u>>|<row|<cell|\<phi\>*v>>>>>,
+    \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \<b-F\><rsub|x>(\<b-U\>)\<equiv\><matrix|<tformat|<table|<row|<cell|\<phi\>*u>>|<row|<cell|\<phi\>*u<rsup|2>+g*<frac|\<phi\><rsup|2>|2>>>|<row|<cell|\<phi\>*u*v>>>>>,
+    \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \<b-F\><rsub|y>(\<b-U\>)\<equiv\><matrix|<tformat|<table|<row|<cell|\<phi\>*v>>|<row|<cell|\<phi\>*u*v>>|<row|<cell|\<phi\>*v<rsup|2>+g*<frac|\<phi\><rsup|2>|2>>>>>>.
+  </equation*>
+
+  Using (<reference|lonlat>), the equations in longitude-latitude coordinates
+  can be written
+
+  <\equation>
+    r*cos \<theta\>*\<partial\><rsub|t>\<b-U\>+<frac|1|d\<lambda\>><big|sum><rsub|f<rsub|x>>*\<b-F\><rsub|x>(\<b-U\>)+<frac|1|d\<theta\>><big|sum><rsub|f<rsub|y>>cos
+    \<theta\>*\<b-F\><rsub|y>(\<b-U\>)=0.<label|lonlat>
+  </equation>
+
+  The differential form can be recovered by taking the limit as
+  <math|d\<lambda\>> and <math|d\<theta\>> tend to zero
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|r*cos
+    \<theta\>*\<partial\><rsub|t>\<phi\>+\<partial\><rsub|\<lambda\>>(\<phi\>*u)+\<partial\><rsub|\<theta\>>(\<phi\>*v*cos
+    \<theta\>)=0,>|<cell|>>|<row|<cell|>|<cell|r*cos
+    \<theta\>*\<partial\><rsub|t>(\<phi\>*u)+\<partial\><rsub|\<lambda\>><left|(>\<phi\>*u<rsup|2>+g*<frac|\<phi\><rsup|2>|2><right|)>+\<partial\><rsub|\<theta\>><left|(>\<phi\>*u*v*cos
+    \<theta\><right|)>=0,>|<cell|>>|<row|<cell|>|<cell|r*cos
+    \<theta\>*\<partial\><rsub|t>(\<phi\>*v)+\<partial\><rsub|\<lambda\>>(\<phi\>*u*v)+\<partial\><rsub|\<theta\>><left|[><left|(>\<phi\>*v<rsup|2>+g*<frac|\<phi\><rsup|2>|2><right|)>*cos
+    \<theta\><right|]>=0.>|<cell|>>>>
+  </eqnarray*>
+
+  This can be rewritten in advective form as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t>\<phi\>+<frac|1|r*cos
+    \<theta\>*>*<left|[>\<partial\><rsub|\<lambda\>>(\<phi\>*u)+\<partial\><rsub|\<theta\>>(\<phi\>*v*cos
+    \<theta\>)<right|]>=0,>|<cell|>>|<row|<cell|>|<cell|\<partial\><rsub|t>u+<frac|1|r*cos
+    \<theta\>*>*(u*\<partial\><rsub|\<lambda\>>u+v*cos
+    \<theta\>*\<partial\><rsub|\<theta\>>
+    u)<with|color|blue|<with|color|green|-<frac|u*v|r>*tan
+    \<theta\>>>+<frac|g|r*cos \<theta\>*>*\<partial\><rsub|\<lambda\>>\<phi\>=0,>|<cell|>>|<row|<cell|>|<cell|\<partial\><rsub|t>v+<frac|1|r*cos
+    \<theta\>*>*(u*\<partial\><rsub|\<lambda\>>v+v*cos \<theta\>
+    \<partial\><rsub|\<theta\>> v)<with|color|green|+<frac|u<rsup|2>|r>*tan
+    \<theta\>>+<frac|g|r>*\<partial\><rsub|\<theta\>>\<phi\><with|color|red|-<frac|g*\<phi\>|2*r>*tan
+    \<theta\>>=0,>|<cell|>>>>
+  </eqnarray*>
+
+  where additional terms (compared to the standard form) are indicated in red
+  and missing terms in green.
+
+  <subsection|Derivation using the ``manifold approach'' of Rossmanith et
+  al., 2004>
+
+  System of ``balance laws'' on general manifolds (equation (95))
+
+  <\equation>
+    \<partial\><rsub|t>\<b-q\>+<frac|1|<sqrt|h>>*\<partial\><rsub|x<rsup|k>>\<b-f\><rsup|k>=<with|math-font-series|bold|\<psi\>><rsub|c>,<label|manifold>
+  </equation>
+
+  with <math|h> the determinant of the metric tensor and
+  <with|mode|math|<with|math-font-series|bold|\<psi\>><rsub|c>> the geometric
+  source terms. For the shallow-water equations
+
+  <\equation*>
+    \<b-q\>(\<b-x\>,t)\<equiv\><matrix|<tformat|<table|<row|<cell|\<phi\>>>|<row|<cell|\<phi\>*u<rsup|1>>>|<row|<cell|\<phi\>*u<rsup|2>>>>>>,<hspace|10pt>\<b-f\><rsup|k>(\<b-q\>,\<b-x\>)\<equiv\><sqrt|h>*<matrix|<tformat|<table|<row|<cell|\<phi\>*u<rsup|k>>>|<row|<cell|T<rsup|k1>>>|<row|<cell|T<rsup|k2>>>>>>,<hspace|10pt><with|math-font-series|bold|\<psi\>><rsub|c>(\<b-q\>,\<b-x\>)\<equiv\><matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|-\<Gamma\><rsub|m
+    n><rsup|1>*T<rsup|n m>>>|<row|<cell|-\<Gamma\><rsub|m n><rsup|2>*T<rsup|n
+    m>>>>>>,
+  </equation*>
+
+  and
+
+  <\equation*>
+    T<rsup|n m>\<equiv\>\<phi\>*u<rsup|n>*u<rsup|m>+<frac|1|2>*g*\<phi\><rsup|2>*h<rsup|n
+    m>.
+  </equation*>
+
+  For a spherical coordinate system with <math|x<rsup|1>=\<lambda\>> the
+  longitude and <math|x<rsup|2>=\<theta\>> the latitude, the metric is
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<b-h\>>|<cell|\<equiv\>>|<cell|<matrix|<tformat|<table|<row|<cell|r<rsup|2>*cos<rsup|2>
+    \<theta\>>|<cell|0>>|<row|<cell|0>|<cell|r<rsup|2>>>>>>,>>|<row|<cell|<sqrt|h>>|<cell|\<equiv\>>|<cell|r<rsup|2>*cos
+    \<theta\>,>>>>
+  </eqnarray*>
+
+  so that
+
+  <\equation*>
+    h<rsup|11>=<frac|1|h<rsub|11>>=<frac|1|r<rsup|2>*cos<rsup|2>
+    \<theta\>>,<hspace|10pt>h<rsup|22>=<frac|1|h<rsub|22>>=<frac|1|r<rsup|2>>,<hspace|10pt>h<rsup|12>=h<rsup|21>=0.
+  </equation*>
+
+  The corresponding Christofell symbols are given by (for a general
+  orthogonal metric)
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<Gamma\><rsub|m
+    n><rsup|k>>|<cell|\<equiv\>>|<cell|<frac|1|2>*h<rsup|\<alpha\>k>(\<partial\><rsub|x<rsup|n>>h<rsub|\<alpha\>m>+\<partial\><rsub|x<rsup|m>>h<rsub|\<alpha\>n>-\<partial\><rsub|x<rsup|\<alpha\>>>h<rsub|m
+    n>),>>|<row|<cell|\<Gamma\><rsup|1>>|<cell|\<equiv\>>|<cell|<frac|1|2*h<rsub|11>>*<matrix|<tformat|<table|<row|<cell|\<partial\><rsub|x<rsup|1>>h<rsub|11>>|<cell|\<partial\><rsub|x<rsup|2>>h<rsub|11>>>|<row|<cell|\<partial\><rsub|x<rsup|2>>h<rsub|11>>|<cell|-\<partial\><rsub|x<rsup|1>>h<rsub|2
+    2>>>>>>=<matrix|<tformat|<table|<row|<cell|0>|<cell|-tan
+    \<theta\>*>>|<row|<cell|-tan \<theta\>*>|<cell|0>>>>>,>>|<row|<cell|\<Gamma\><rsup|2>>|<cell|\<equiv\>>|<cell|<frac|1|2*h<rsub|22>>*<matrix|<tformat|<table|<row|<cell|-\<partial\><rsub|x<rsup|2>>h<rsub|11>>|<cell|\<partial\><rsub|x<rsup|1>>h<rsub|22>>>|<row|<cell|\<partial\><rsub|x<rsup|1>>h<rsub|22>>|<cell|\<partial\><rsub|x<rsup|2>>h<rsub|2
+    2>>>>>>=<matrix|<tformat|<table|<row|<cell|*sin \<theta\>*cos
+    \<theta\>>|<cell|0>>|<row|<cell|0>|<cell|0>>>>>.>>>>
+  </eqnarray*>
+
+  The geometric source term is then
+
+  <\equation*>
+    <hspace|10pt><with|math-font-series|bold|\<psi\>><rsub|c>(\<b-q\>,\<b-x\>)\<equiv\><matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|tan
+    \<theta\>*(T<rsup|1 2>+*T<rsup|2 1>)>>|<row|<cell|-sin \<theta\>*cos
+    \<theta\>*T<rsup|11>>>>>>=<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|2*tan
+    \<theta\>*\<phi\>*u<rsup|1>*u<rsup|2>>>|<row|<cell|-sin \<theta\>*cos
+    \<theta\>*\<phi\>*u<rsup|1>*u<rsup|1>-<frac|g*\<phi\><rsup|2>|2*r<rsup|2>*>*tan
+    \<theta\>>>>>>
+  </equation*>
+
+  Equation (<reference|manifold>) can be developed as
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<partial\><rsub|t>\<phi\>+<frac|1|cos
+    \<theta\>>*<left|[>\<partial\><rsub|\<lambda\>>(*cos
+    \<theta\>*\<phi\>*u<rsup|1>)+\<partial\><rsub|\<theta\>>(cos
+    \<theta\>*\<phi\>*u<rsup|2>)<right|]>>|<cell|=>|<cell|0,>>|<row|<cell|\<partial\><rsub|t>(\<phi\>*u<rsup|1>)+<frac|1|cos
+    \<theta\>>*<left|[>\<partial\><rsub|\<lambda\>>(cos
+    \<theta\>*(\<phi\>*u<rsup|1>*u<rsup|1>+<frac|g*\<phi\><rsup|2>|2*r<rsup|2>*cos<rsup|2>\<theta\>>))+\<partial\><rsub|\<theta\>>(cos
+    \<theta\>*\<phi\>*u<rsup|1>*u<rsup|2>)<right|]>>|<cell|=>|<cell|-\<Gamma\><rsub|m
+    n><rsup|1>*T<rsup|n m>,>>|<row|<cell|\<partial\><rsub|t>(\<phi\>*u<rsup|2>)+<frac|1|cos
+    \<theta\>>*<left|[>\<partial\><rsub|\<lambda\>>(cos
+    \<theta\>**\<phi\>*u<rsup|1>*u<rsup|2>)+\<partial\><rsub|\<theta\>>(cos
+    \<theta\>*(\<phi\>*u<rsup|2>*u<rsup|2>+<frac|g*\<phi\><rsup|2>|2*r<rsup|2>*>))<right|]>>|<cell|=>|<cell|-\<Gamma\><rsub|m
+    n><rsup|2>*T<rsup|n m>.>>>>
+  </eqnarray*>
+
+  Using
+
+  <\equation*>
+    u\<equiv\>u<rsub|1>\<equiv\>r*cos \<theta\>
+    u<rsup|1>,<hspace|10pt>v\<equiv\>u<rsub|2>\<equiv\>r*u<rsup|2>,
+  </equation*>
+
+  (where exponents and indices indicate the covariant and contravariant
+  vector coordinates respectively) then gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<partial\><rsub|t>\<phi\>+<frac|1|r*cos
+    \<theta\>>*<left|[>\<partial\><rsub|\<lambda\>>(\<phi\>*u)+\<partial\><rsub|\<theta\>>(cos
+    \<theta\>*\<phi\>*v)<right|]>>|<cell|=>|<cell|0,>>|<row|<cell|\<partial\><rsub|t>u+<frac|1|r*cos
+    \<theta\>*>*(u*\<partial\><rsub|\<lambda\>>u+cos
+    \<theta\>*v*\<partial\><rsub|\<theta\>>u)+<frac|g|r*cos
+    \<theta\>>*\<partial\><rsub|\<lambda\>>\<phi\>-<frac|u*v|r>*tan
+    \<theta\>>|<cell|=>|<cell|*0,>>|<row|<cell|\<partial\><rsub|t>v+<frac|1|r*cos
+    \<theta\>>*(u*\<partial\><rsub|\<lambda\>>v+cos
+    \<theta\>*v**\<partial\><rsub|\<theta\>>*v)+<frac|g|r>*\<partial\><rsub|\<theta\>>\<phi\>>|<cell|=>|<cell|-<frac|u*u|r*>*tan
+    \<theta\>,>>>>
+  </eqnarray*>
+
+  which is the standard advective form.
+
+  The geometric source term can be re-expressed in the covariant coordinate
+  system as
+
+  <\equation*>
+    <hspace|10pt><with|math-font-series|bold|<wide|\<psi\>|^>>\<equiv\><matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|2*tan
+    \<theta\>*\<phi\>*<frac|u<rsub|1>*u<rsub|2>|r*>>>|<row|<cell|-tan
+    \<theta\>*\<phi\>*<frac|u<rsub|1>*u<rsub|1>|r*>-<frac|g*\<phi\><rsup|2>|2*r*>*tan
+    \<theta\>>>>>>
+  </equation*>
+
+  <subsection|The Saint-Venant equations in general orthogonal coordinates>
+
+  \;
+
+  <\equation*>
+    h<rsub|\<lambda\>>*h<rsub|\<theta\>>*d\<lambda\>*d\<theta\>*\<partial\><rsub|t>\<b-U\>+<big|sum><rsub|f<rsub|\<lambda\>>>h<rsub|\<theta\>>*d\<theta\>*\<b-F\><rsub|\<lambda\>>(\<b-U\>)+<big|sum><rsub|f<rsub|\<theta\>>>h<rsub|\<lambda\>>*d\<lambda\>*\<b-F\><rsub|\<theta\>>(\<b-U\>)=0
+  </equation*>
+
+  can be rewritten
+
+  <\equation*>
+    h<rsub|\<lambda\>>*h<rsub|\<theta\>>*\<partial\><rsub|t>\<b-U\>+<frac|1|d\<lambda\>>*<big|sum><rsub|f<rsub|\<lambda\>>>h<rsub|\<theta\>>*\<b-F\><rsub|\<lambda\>>(\<b-U\>)+<frac|1|d\<theta\>>*<big|sum><rsub|f<rsub|\<theta\>>>h<rsub|\<lambda\>>*\<b-F\><rsub|\<theta\>>(\<b-U\>)=0.
+  </equation*>
+
+  The differential form can be recovered by making <math|d\<lambda\>> and
+  <math|d\<theta\>> tend to zero
+
+  <\with|mode|math>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|>|<cell|h<rsub|\<lambda\>>*h<rsub|\<theta\>>*\<partial\><rsub|t>\<phi\>+\<partial\><rsub|\<lambda\>>(h<rsub|\<theta\>>*\<phi\>*u)+\<partial\><rsub|\<theta\>>(h<rsub|\<lambda\>>*\<phi\>*v)=0,>|<cell|>>|<row|<cell|>|<cell|h<rsub|\<lambda\>>*h<rsub|\<theta\>>*\<partial\><rsub|t>(\<phi\>*u)+\<partial\><rsub|\<lambda\>><left|[>h<rsub|\<theta\>>*<left|(>\<phi\>*u<rsup|2>+g*<frac|\<phi\><rsup|2>|2><right|)><right|]>+\<partial\><rsub|\<theta\>><left|(>h<rsub|\<lambda\>>*\<phi\>*u*v<right|)>=0,>|<cell|>>|<row|<cell|>|<cell|h<rsub|\<lambda\>>*h<rsub|\<theta\>>*\<partial\><rsub|t>(\<phi\>*v)+\<partial\><rsub|\<lambda\>>(h<rsub|\<theta\>>*\<phi\>*u*v)+\<partial\><rsub|\<theta\>><left|[>h<rsub|\<lambda\>>*<left|(>\<phi\>*v<rsup|2>+g*<frac|\<phi\><rsup|2>|2><right|)><right|]>=0.>|<cell|>>>>
+    </eqnarray*>
+  </with>
+
+  which can be expanded as
+
+  <\with|mode|math>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|>|<cell|\<partial\><rsub|t>\<phi\>+<frac|u*|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>\<phi\>*+<frac|v*|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>\<phi\>+<frac|\<phi\>*|h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*<left|[>\<partial\><rsub|\<lambda\>>(h<rsub|\<theta\>>*u)+\<partial\><rsub|\<theta\>>(h<rsub|\<lambda\>>*v)<right|]>=0,>|<cell|>>|<row|<cell|>|<cell|\<partial\><rsub|t>u*+<frac|u*|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>u+<frac|v*|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>u*+<frac|g|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>\<phi\>+g*<frac|\<phi\>|2*h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*\<partial\><rsub|\<lambda\>>h<rsub|\<theta\>>=0,>|<cell|>>|<row|<cell|>|<cell|\<partial\><rsub|t>v+<frac|u|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>v+<frac|v|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>v+<frac|g|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>\<phi\>+g*<frac|\<phi\>|2*h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>h<rsub|\<lambda\>>=0.>|<cell|>>>>
+    </eqnarray*>
+  </with>
+
+  Introducing the notation
+
+  <\equation*>
+    d<rsub|t>=\<partial\><rsub|t>+<frac|u*|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>+<frac|v*|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>,
+  </equation*>
+
+  this can be rewritten
+
+  <\with|mode|math>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|>|<cell|d<rsub|t>\<phi\>+<frac|\<phi\>*|h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*<left|[>\<partial\><rsub|\<lambda\>>(h<rsub|\<theta\>>*u)+\<partial\><rsub|\<theta\>>(h<rsub|\<lambda\>>*v)<right|]>=0,>|<cell|>>|<row|<cell|>|<cell|d<rsub|t>u*<with|color|blue|<with|color|green|<with|color|green|-f<rsub|G>*v>>>+<frac|g|h<rsub|\<lambda\>>>*\<partial\><rsub|\<lambda\>>\<phi\><with|color|red|+<frac|g*\<phi\>|2*h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*\<partial\><rsub|\<lambda\>>h<rsub|\<theta\>>>=0,>|<cell|<eq-number><label|general-u>>>|<row|<cell|>|<cell|d<rsub|t>v<with|color|green|<with|color|blue|<with|color|green|+f<rsub|G>*u>>>+<frac|g|h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>\<phi\><with|color|red|+*<frac|g*\<phi\>|2*h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*\<partial\><rsub|\<theta\>>h<rsub|\<lambda\>>>=0.>|<cell|>>>>
+    </eqnarray*>
+  </with>
+
+  where additional and missing terms (respective to equations 43, 44 and 45
+  of Williamson et al, 1991) are indicated in red and green respectively and
+
+  <\equation*>
+    f<rsub|G>\<equiv\><frac|v*\<partial\><rsub|\<lambda\>>h<rsub|\<theta\>>-u*\<partial\><rsub|\<theta\>>h<rsub|\<lambda\>>|h<rsub|\<lambda\>>*h<rsub|\<theta\>>>*.*
+  </equation*>
+
+  <subsubsection|Application to spherical coordinates>
+
+  For spherical coordinates
+
+  <\equation*>
+    h<rsub|\<lambda\>>=r*cos \<theta\>,<hspace|10pt>h<rsub|\<theta\>>=r,<hspace|10pt>\<partial\><rsub|\<lambda\>>h<rsub|\<theta\>>=0,<hspace|10pt>\<partial\><rsub|\<theta\>>h<rsub|\<lambda\>>=-r*sin
+    \<theta\>,
+  </equation*>
+
+  which gives
+
+  <\with|mode|math>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|>|<cell|d<rsub|t>\<phi\>+<frac|\<phi\>*|r*cos
+      \<theta\>>*<left|[>\<partial\><rsub|\<lambda\>>u+\<partial\><rsub|\<theta\>>(v*cos
+      \<theta\>)<right|]>=0,>|<cell|>>|<row|<cell|>|<cell|d<rsub|t>u*<with|color|blue|<with|color|green|<with|color|green|-<frac|u*v|r>*tan
+      \<theta\>>>>+<frac|g|r*cos \<theta\>>*\<partial\><rsub|\<lambda\>>\<phi\>=0,>|<cell|>>|<row|<cell|>|<cell|d<rsub|t>v<with|color|green|<with|color|blue|<with|color|green|<with|color|green|+<frac|u<rsup|2>|r>*tan
+      \<theta\>>>>>+<frac|g|r>*\<partial\><rsub|\<theta\>>\<phi\><with|color|red|-<frac|g*\<phi\>|2*r>*tan
+      \<theta\>>=0.>|<cell|>>>>
+    </eqnarray*>
+  </with>
+
+  <subsubsection|Application to polar coordinates>
+
+  For polar coordinates
+
+  <\equation*>
+    h<rsub|\<lambda\>>=1,<hspace|10pt>h<rsub|\<theta\>>=\<lambda\>,<hspace|10pt>\<partial\><rsub|\<lambda\>>h<rsub|\<theta\>>=1,<hspace|10pt>\<partial\><rsub|\<theta\>>h<rsub|\<lambda\>>=0,
+  </equation*>
+
+  which gives
+
+  <\with|mode|math>
+    <\eqnarray*>
+      <tformat|<table|<row|<cell|>|<cell|d<rsub|t>\<phi\>+<frac|\<phi\>*|\<lambda\>>*<left|[>\<partial\><rsub|\<lambda\>>(\<lambda\>*u)+\<partial\><rsub|\<theta\>>v<right|]>=0,>|<cell|>>|<row|<cell|>|<cell|d<rsub|t>u*<with|color|blue|<with|color|green|<with|color|green|-<frac|v<rsup|2>|\<lambda\>>>>>+g*\<partial\><rsub|\<lambda\>>\<phi\><with|color|red|+g*<frac|\<phi\>|2*\<lambda\>>>=0,>|<cell|>>|<row|<cell|>|<cell|d<rsub|t>v<with|color|green|<with|color|blue|<with|color|green|<with|color|green|+<frac|u*v|\<lambda\>>>>>>+<frac|g|\<lambda\>>*\<partial\><rsub|\<theta\>>\<phi\>=0.>|<cell|>>>>
+    </eqnarray*>
+  </with>
+
+  <subsection|``Well-balanced'' scheme in general orthogonal coordinates>
+
+  From Audusse et al, 2004, the one-dimensional scheme in Cartesian
+  coordinates can be written
+
+  <\equation>
+    \<Delta\>x<rsub|i>*d<rsub|t>U<rsub|i>+\<cal-F\><rsub|l>-\<cal-F\><rsub|r>=S<rsub|ci>,<label|audusse>
+  </equation>
+
+  with left and right numerical fluxes
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<cal-F\><rsub|l>>|<cell|=>|<cell|\<cal-F\>(U<rsub|i+1/2->,U<rsub|i+1/2+>)+<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|\<phi\><rsup|2><rsub|i,r>-\<phi\><rsup|2><rsub|i+1/2->>>>>>,>>|<row|<cell|\<cal-F\><rsub|r>>|<cell|=>|<cell|\<cal-F\>(U<rsub|i-1/2->,U<rsub|i-1/2+>)+<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|\<phi\><rsup|2><rsub|i,l>-\<phi\><rsup|2><rsub|i-1/2+>>>>>>,>>>>
+  </eqnarray*>
+
+  and centered source term (necessary to correct second-order imbalances)
+
+  <\equation*>
+    S<rsub|ci>=<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|(\<phi\><rsub|i,l>+\<phi\><rsub|i,r>)*(z<rsub|i,l>-z<rsub|i,r>)>>>>>.
+  </equation*>
+
+  The lake-at-rest steady state is defined by <math|u<rsub|i>=0> and
+  <math|\<phi\><rsub|i,l>+z<rsub|i,l>=\<phi\><rsub|i,r>+z<rsub|i,r>=\<phi\><rsub|i>+z<rsub|i>=H>
+  for all <math|i>. In this case
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|\<cal-F\><rsub|l>>|<cell|=>|<cell|<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|*\<phi\><rsup|2><rsub|i+1/2->>>>>>+<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|\<phi\><rsup|2><rsub|i,r>-\<phi\><rsup|2><rsub|i+1/2->>>>>>,>>|<row|<cell|\<cal-F\><rsub|r>>|<cell|=>|<cell|<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|\<phi\><rsup|2><rsub|i-1/2+>>>>>>+<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|*\<phi\><rsup|2><rsub|i,l>-\<phi\><rsup|2><rsub|i-1/2+>>>>>>.>>>>
+  </eqnarray*>
+
+  The centered source term becomes
+
+  <\equation*>
+    S<rsub|ci>=<frac|g|2>**<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|(\<phi\><rsub|i,l>+\<phi\><rsub|i,r>)*(H-\<phi\><rsub|i,l>-H+\<phi\><rsub|i,r>)>>>>>=<frac|g|2>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|\<phi\><rsup|2><rsub|i,r>-\<phi\><rsup|2><rsub|i,l>>>>>>,
+  </equation*>
+
+  and restores hydrostatic balance.
+
+  For general orthogonal coordinates (<reference|audusse>) can be rewritten
+
+  <\equation*>
+    \<Delta\>x<rsub|i>*c<rsub|i>*d<rsub|t>U<rsub|i>+s<rsub|l>*\<cal-F\><rsub|l>-s<rsub|r>*\<cal-F\><rsub|r>=S<rsub|ci>+S<rsub|g>.
+  </equation*>
+
+  For the lake-at-rest steady state, this gives for the velocity component
+  <math|u>
+
+  <\equation*>
+    \<Delta\>x<rsub|i>*c<rsub|i>*d<rsub|t>u+<frac|g|2>*(s<rsub|l>*\<phi\><rsup|2><rsub|i,r>-s<rsub|r>*\<phi\><rsup|2><rsub|i,l>)=S<rsub|ci>+S<rsub|g>,
+  </equation*>
+
+  with the geometric source term (red term in (<reference|general-u>))
+  discretised as
+
+  <\equation*>
+    S<rsub|g>\<equiv\><frac|g|4>*(\<phi\><rsup|2><rsub|i,r>+\<phi\><rsup|2><rsub|i,l>)*(s<rsub|l>-s<rsub|r>).
+  </equation*>
+
+  The definition of <math|S<rsub|ci>> thus needs to be modified to maintain
+  balance, a simple choice is
+
+  <\equation*>
+    S<rsub|ci>=<frac|g|4>*<matrix|<tformat|<table|<row|<cell|0>>|<row|<cell|(s<rsub|l>+s<rsub|r>)*(\<phi\><rsub|i,l>+\<phi\><rsub|i,r>)*(z<rsub|i,l>-z<rsub|i,r>)>>>>>,
+  </equation*>
+
+  which for the lake-at-rest steady-state gives
+
+  <\eqnarray*>
+    <tformat|<table|<row|<cell|<frac|2|g>*\<Delta\>x<rsub|i>*c<rsub|i>*d<rsub|t>u>|<cell|=>|<cell|<frac|1|2>*(s<rsub|l>+s<rsub|r>)*(\<phi\><rsup|2><rsub|i,r>-\<phi\><rsup|2><rsub|i,l>)*+<frac|\<phi\><rsup|2><rsub|i,r>+\<phi\><rsup|2><rsub|i,l>|2>*(s<rsub|l>-s<rsub|r>)-s<rsub|l>*\<phi\><rsup|2><rsub|i,r>+s<rsub|r>*\<phi\><rsup|2><rsub|i,l>>>|<row|<cell|>|<cell|=>|<cell|0.>>>>
+  </eqnarray*>
+
+  This scheme also reduces to the Cartesian scheme for
+  <math|s<rsub|l>=s<rsub|r>=c<rsub|i>=1> and to the first-order scheme for
+  <math|z<rsub|i,l>=z<rsub|i,r>=z<rsub|i>> and
+  <math|<rsub|>\<phi\><rsub|i,r>=\<phi\><rsub|i,l>=\<phi\><rsub|i>>.
+</body>
+
+<\references>
+  <\collection>
+    <associate|audusse|<tuple|7|4>>
+    <associate|auto-1|<tuple|1|1>>
+    <associate|auto-2|<tuple|1|1>>
+    <associate|auto-3|<tuple|2|2>>
+    <associate|auto-4|<tuple|3|3>>
+    <associate|auto-5|<tuple|3.1|4>>
+    <associate|auto-6|<tuple|3.2|4>>
+    <associate|auto-7|<tuple|4|4>>
+    <associate|conservation|<tuple|1|1>>
+    <associate|general-u|<tuple|6|4>>
+    <associate|gerris|<tuple|2|1>>
+    <associate|lonlat|<tuple|4|2>>
+    <associate|manifold|<tuple|5|2>>
+  </collection>
+</references>
+
+<\auxiliary>
+  <\collection>
+    <\associate|figure>
+      <tuple|normal|Elementary lengths for a surface
+      element.|<pageref|auto-1>>
+    </associate>
+    <\associate|toc>
+      <with|par-left|<quote|1.5fn>|1<space|2spc>Application to the
+      Saint-Venant equations <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-2>>
+
+      <with|par-left|<quote|1.5fn>|2<space|2spc>Derivation using the
+      ``manifold approach'' of Rossmanith et al., 2004
+      <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-3>>
+
+      <with|par-left|<quote|1.5fn>|3<space|2spc>The Saint-Venant equations in
+      general orthogonal coordinates <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-4>>
+
+      <with|par-left|<quote|3fn>|3.1<space|2spc>Application to spherical
+      coordinates <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-5>>
+
+      <with|par-left|<quote|3fn>|3.2<space|2spc>Application to polar
+      coordinates <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-6>>
+
+      <with|par-left|<quote|1.5fn>|4<space|2spc>``Well-balanced'' scheme in
+      general orthogonal coordinates <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
+      <no-break><pageref|auto-7>>
+    </associate>
+  </collection>
+</auxiliary>
\ No newline at end of file
diff --git a/doc/figures/match.fig b/doc/figures/match.fig
new file mode 100644
index 0000000..6a5bb91
--- /dev/null
+++ b/doc/figures/match.fig
@@ -0,0 +1,129 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 3000 300 4200 1500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 300 4200 300 4200 1500 3000 1500 3000 300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 300 3600 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 900 4200 900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3300 300 3300 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3900 300 3900 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 600 4200 600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 1200 4200 1200
+-6
+6 3000 1800 4200 3000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 1800 4200 1800 4200 3000 3000 3000 3000 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 1800 3600 3000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 2400 4200 2400
+-6
+6 5700 1800 6900 3000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 5700 1800 6900 1800 6900 3000 5700 3000 5700 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6300 1800 6300 3000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 5700 2400 6900 2400
+-6
+6 7200 300 8400 1500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 300 8400 300 8400 1500 7200 1500 7200 300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7800 300 7800 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 900 8400 900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7500 300 7500 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 8100 300 8100 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 600 8400 600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 1200 8400 1200
+-6
+6 7200 1800 8400 3000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 1800 8400 1800 8400 3000 7200 3000 7200 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7800 1800 7800 3000
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 2400 8400 2400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 2100 8400 2100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7500 1800 7500 2400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 8100 1800 8100 2400
+-6
+6 3000 5100 4200 6300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 5100 4200 5100 4200 6300 3000 6300 3000 5100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 5100 3600 6300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 5700 4200 5700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3300 5100 3300 6300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3900 5100 3900 6300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 5400 4200 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 6000 4200 6000
+-6
+6 3000 6600 4200 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 6600 4200 6600 4200 7800 3000 7800 3000 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 6600 3600 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 7200 4200 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 6900 4200 6900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3300 6600 3300 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3900 6600 3900 7200
+-6
+6 1500 6600 2700 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1500 6600 2700 6600 2700 7800 1500 7800 1500 6600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 6600 2100 7800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1500 7200 2700 7200
+-6
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1500 1800 2700 1800 2700 3000 1500 3000 1500 1800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1500 3300 2700 3300 2700 4500 1500 4500 1500 3300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 5700 3300 6900 3300 6900 4500 5700 4500 5700 3300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1500 8100 2700 8100 2700 9300 1500 9300 1500 8100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2400 6600 2400 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 6900 2700 6900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 1
+	 5700 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 1
+	 5700 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 2100 8100 2100 9300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1500 8700 2700 8700
diff --git a/doc/figures/parabola.fig b/doc/figures/parabola.fig
new file mode 100644
index 0000000..7134fcc
--- /dev/null
+++ b/doc/figures/parabola.fig
@@ -0,0 +1,136 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+A4      
+100.00
+Single
+-2
+1200 2
+6 4050 1950 4350 2250
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4275 2025 4125 2175
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4125 2025 4275 2175
+-6
+6 4050 5550 4350 5850
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4275 5625 4125 5775
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4125 5625 4275 5775
+-6
+6 4050 3150 4350 3450
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4275 3225 4125 3375
+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4125 3225 4275 3375
+-6
+6 5775 5475 9525 5775
+4 0 0 50 0 32 18 0.0000 4 195 165 5775 5700 D\001
+4 0 0 50 0 1 18 0.0000 4 255 3510 6000 5700 p = -2/9 p6 - 8/27 p7 + 14/27 p\001
+-6
+6 5775 4875 9225 5175
+4 0 0 50 0 32 18 0.0000 4 195 165 5775 5100 D\001
+4 0 0 50 0 1 18 0.0000 4 255 3180 6000 5100 p = -1/3 p6 -1/5 p5 + 8/15 p\001
+-6
+6 7200 6600 9600 9000
+6 8625 7875 8775 8025
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 8738 7912 8662 7988
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 8662 7912 8738 7988
+-6
+1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 8250 7950 47 47 8250 7950 8235 7995
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 7800 8400 7800 8400 8400 7800 8400 7800 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8400 7800 9000 7800 9000 8400 8400 8400 8400 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 7200 8400 7200 8400 7800 7800 7800 7800 7200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 8100 7800 8100 8400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7800 8100 8400 8100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8400 6600 9600 6600 9600 7800 8400 7800 8400 6600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 6600 8400 6600 8400 7800 7200 7800 7200 6600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 7800 8400 7800 8400 9000 7200 9000 7200 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8400 7800 9600 7800 9600 9000 8400 9000 8400 7800
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 6600 7800 6600 7800 7200 7200 7200 7200 6600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 9000 8400 9600 8400 9600 9000 9000 9000 9000 8400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7200 8400 7800 8400 7800 9000 7200 9000 7200 8400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8664 8065 8739 8065 8739 8139 8664 8139 8664 8065
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8925 7125 9075 7125 9075 7275 8925 7275 8925 7125
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 8663 8661 8738 8661 8738 8735 8663 8735 8663 8661
+4 0 0 50 0 0 12 0.0000 4 135 75 8771 7998 ?\001
+-6
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 3600 2100 75 75 3600 2100 3675 2100
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4800 2100 75 75 4800 2100 4875 2100
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 3600 5700 75 75 3600 5700 3675 5700
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4800 5700 75 75 4800 5700 4875 5700
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2400 3300 75 75 2400 3300 2475 3300
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 1200 3300 75 75 1200 3300 1275 3300
+1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1500 3000 47 47 1500 3000 1485 3045
+1 3 0 1 0 7 50 0 -1 0.000 1 0.0000 1500 3600 47 47 1500 3600 1485 3645
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 2700 5400 2700 5400 5100 3000 5100 3000 2700
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 300 5400 300 5400 2700 3000 2700 3000 300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3000 5100 5400 5100 5400 7500 3000 7500 3000 5100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4125 3825 4275 3825 4275 3975 4125 3975 4125 3825
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4125 6225 4275 6225 4275 6375 4125 6375 4125 6225
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4125 1425 4275 1425 4275 1575 4125 1575 4125 1425
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4200 300 4200 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 1500 5400 1500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4200 5100 4200 7500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3000 6300 5400 6300
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 2700 3000 2700 3000 5100 600 5100 600 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1800 2700 1800 5100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 3900 3000 3900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2700 1200 3900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 3300 1800 3300
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1425 3225 1575 3375
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1575 3225 1425 3375
+2 1 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 2
+	 3075 3225 2925 3375
+2 1 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 2
+	 2925 3225 3075 3375
+4 0 0 50 0 1 12 0.0000 4 180 180 900 3150 p5\001
+4 0 0 50 0 1 18 0.0000 4 255 270 4425 1350 p2\001
+4 0 0 50 0 1 18 0.0000 4 255 270 4425 2475 p3\001
+4 0 0 50 0 1 18 0.0000 4 180 135 4425 3375 p\001
+4 0 0 50 0 1 18 0.0000 4 255 270 4425 3975 p0\001
+4 0 0 50 0 1 18 0.0000 4 255 270 4425 5475 p4\001
+4 0 0 50 0 1 18 0.0000 4 255 270 4425 6675 p1\001
+4 0 0 50 0 32 12 0.0000 4 135 120 3150 3375 D\001
+4 0 0 50 0 1 12 0.0000 4 180 180 1575 3150 p7\001
+4 0 0 50 0 1 12 0.0000 4 180 180 2175 3150 p6\001
+4 0 0 50 0 1 12 0.0000 4 135 90 3300 3375 p\001
+4 0 0 50 0 1 18 0.0000 4 255 3615 6000 2400 p = 15/16 p0 - 3/32 p1 + 5/32 p2\001
+4 0 0 50 0 1 18 0.0000 4 255 3345 6000 3000 p = 5/6 p0 - 1/14 p1 + 5/21 p3\001
+4 0 0 50 0 1 18 0.0000 4 255 2670 6000 3600 p = p0 - 1/7 p4 + 1/7 p2\001
+4 0 0 50 0 1 18 0.0000 4 255 3075 6000 4200 p = 8/9 p0 - 1/9 p4 + 2/9 p3\001
diff --git a/doc/figures/plicheight.fig b/doc/figures/plicheight.fig
new file mode 100644
index 0000000..e479eb7
--- /dev/null
+++ b/doc/figures/plicheight.fig
@@ -0,0 +1,35 @@
+#FIG 3.2  Produced by xfig version 3.2.5-alpha5
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+6 2700 2250 4950 7200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2700 2250 4950 2250 4950 4725 2700 4725 2700 2250
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2700 4725 4950 4725 4950 7200 2700 7200 2700 4725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 2700 5400 4050 4725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 4275 4725 4950 4050
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 1 2.00 120.00 240.00
+	 3825 6075 3825 4845
+4 0 4 50 -1 0 20 0.0000 4 225 180 4005 5565 H\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5850 2250 8100 2250 8100 4725 5850 4725 5850 2250
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5850 4725 8100 4725 8100 7200 5850 7200 5850 4725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5850 5400 6860 4723
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 7080 4728 8100 4050
+2 1 1 2 4 7 50 -1 -1 4.500 0 0 -1 1 0 2
+	1 1 2.00 120.00 240.00
+	 6975 6075 6976 4046
+4 0 4 50 -1 0 20 0.0000 4 225 285 7155 5565 H?\001
diff --git a/doc/figures/thin.fig b/doc/figures/thin.fig
new file mode 100644
index 0000000..8b88477
--- /dev/null
+++ b/doc/figures/thin.fig
@@ -0,0 +1,151 @@
+#FIG 3.2  Produced by xfig version 3.2.5-alpha5
+Landscape
+Center
+Metric
+A4      
+100.00
+Single
+-2
+1200 2
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 3600 450 4500 450 4500 1350 3600 1350 3600 450
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 450 5850 450 5850 1350 4950 1350 4950 450
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 4050 450 3600 900
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5400 450 5400 1350
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 3600 3600 3825 3150
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 4275 3150 4500 3600
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 3600 5850 4500 5850 4500 6750 3600 6750 3600 5850
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
+	 3375 6075 3825 6300 3375 6525
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 3600 1800 4500 1800 4500 2700 3600 2700 3600 1800
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4050 1800 3600 2250
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4500 2250 4050 2700
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 3600 3150 4500 3150 4500 4050 3600 4050 3600 3150
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 6300 3150 7200 3150 7200 4050 6300 4050 6300 3150
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 6300 3600 7200 3600
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 6750 3150 7200 3375
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 7650 3150 8550 3150 8550 4050 7650 4050 7650 3150
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 7650 3600 8100 3150
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 8775 3375 8325 3600
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 8325 3600 8775 3825
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 3600 4500 4500 4500 4500 5400 3600 5400 3600 4500
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4500 5175 4275 5400
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4500 4725 3825 5400
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 4950 4050 4500
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 4500 5850 4500 5850 5400 4950 5400 4950 4500
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 5850 4725 5400 4500
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 4950 5175 5400
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 5625 5400 5850 5175
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 3600 7200 4500 7200 4500 8100 3600 8100 3600 7200
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 7875 4500 7875
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 7425 4500 7425
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 7200 5850 7200 5850 8100 4950 8100 4950 7200
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 7425 5175 7200
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 7875 5625 7200
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 6300 7200 7200 7200 7200 8100 6300 8100 6300 7200
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 6975 6750 7425 6975 6975
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 8325 6750 7875 6975 8325
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 3600 8550 4500 8550 4500 9450 3600 9450 3600 8550
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 9000 4500 9000
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 8775 3825 8550
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4275 8550 4500 8775
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 9000 5400 8550
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 8775 5175 8550
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 8550 5850 8550 5850 9450 4950 9450 4950 8550
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 5175 9675 5400 9225 5625 9675
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 6300 8550 7200 8550 7200 9450 6300 9450 6300 8550
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 8325 6750 8775 6975 8325
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 9675 6750 9225 6975 9675
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 7425 8775 6975 9000 7425 9225
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 3600 9900 4500 9900 4500 10800 3600 10800 3600 9900
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3600 10125 3825 9900
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 3825 10800 3600 10575
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4500 10575 4275 10800
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4275 9900 4500 10125
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 9900 5850 9900 5850 10800 4950 10800 4950 9900
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 5400 9900 4950 10350
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 10125 5175 9900
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 5850 10350 5400 10800
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 5850 10575 5625 10800
+2 2 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 6300 9900 7200 9900 7200 10800 6300 10800 6300 9900
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 9675 6750 10125 6975 9675
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6075 10125 6525 10350 6075 10575
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 6525 11025 6750 10575 6975 11025
+2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 7425 10125 6975 10350 7425 10575
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2
+	 4950 3600 5850 3600
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+	 4950 3150 5850 3150 5850 4050 4950 4050 4950 3150
+2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 3
+	 5175 2925 5400 3375 5625 2925
+4 0 0 50 -1 16 20 0.0000 4 255 2685 450 675 odd = 2 even = 0: \001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 2025 odd = 4 even = 0:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 3375 odd = 2 even = 1:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 4725 odd = 2 even = 2:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 6075 odd = 0 even = 1:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 7425 odd = 0 even = 2:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 8775 odd = 0 even = 3:\001
+4 0 0 50 -1 16 20 0.0000 4 255 2595 450 10125 odd = 0 even = 4:\001
+4 0 4 50 -1 16 20 0.0000 4 255 1200 9450 6075 red: thin\001
+4 0 0 50 -1 16 20 0.0000 4 255 1665 9450 6525 black: thick\001
diff --git a/doc/figures/topology.fig b/doc/figures/topology.fig
new file mode 100644
index 0000000..4de22b2
--- /dev/null
+++ b/doc/figures/topology.fig
@@ -0,0 +1,134 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 300 3225 4275 6975
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 3900 1800 3900 1800 5100 600 5100 600 3900
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1800 3900 4200 3900 4200 6300 1800 6300 1800 3900
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4200 3300 600 6900
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 3300 4200 6900
+3 0 0 2 0 7 50 0 -1 0.000 0 0 0 4
+	 3000 3675 1650 4500 900 5325 375 6375
+	 0.000 1.000 1.000 0.000
+4 0 0 50 0 0 24 0.0000 4 255 930 2550 5175 mixed\001
+4 0 0 50 0 0 18 0.0000 4 195 690 900 4575 mixed\001
+-6
+6 6300 3600 10200 6450
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6600 3900 7800 3900 7800 5100 6600 5100 6600 3900
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 3900 10200 3900 10200 6300 7800 6300 7800 3900
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7800 5100 10200 5100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 9000 3900 9000 6300
+3 0 0 2 0 7 50 0 -1 0.000 0 0 0 4
+	 9000 3675 7650 4500 6900 5325 6375 6375
+	 0.000 1.000 1.000 0.000
+4 0 0 50 0 0 18 0.0000 4 195 690 6900 4575 mixed\001
+4 0 0 50 0 0 18 0.0000 4 195 510 9375 4575 fluid\001
+4 0 0 50 0 0 18 0.0000 4 195 510 9375 5775 fluid\001
+4 0 0 50 0 0 18 0.0000 4 195 510 8175 5775 fluid\001
+4 0 0 50 0 0 18 0.0000 4 195 690 8100 4575 mixed\001
+-6
+6 6600 7200 10200 11625
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6600 8100 7800 8100 7800 9300 6600 9300 6600 8100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 8100 10200 8100 10200 10500 7800 10500 7800 8100
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 9000 8100 9000 10500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7800 9300 9000 9300
+3 0 0 2 0 7 50 0 -1 0.000 0 0 0 4
+	 7875 7275 8325 8775 8400 10125 7800 11550
+	 0.000 1.000 1.000 0.000
+4 0 0 50 0 0 18 0.0000 4 195 510 6975 8775 fluid\001
+4 0 0 50 0 0 18 0.0000 4 195 690 8100 8775 mixed\001
+4 0 0 50 0 0 18 0.0000 4 195 690 8100 9975 mixed\001
+-6
+6 525 7425 4275 11175
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4200 7500 600 11100
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 7500 4200 11100
+-6
+6 4425 9075 6375 9750
+2 1 0 10 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 360.00 270.00
+	 4500 9300 6300 9300
+4 0 0 50 0 0 12 0.0000 4 180 1320 4725 9675 fl_refine_mixed()\001
+-6
+6 375 11625 4425 15825
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1800 12000 4200 12000 4200 14400 1800 14400 1800 12000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1800 14400 3000 14400 3000 15600 1800 15600 1800 14400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 14400 1800 14400 1800 15600 600 15600 600 14400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 13200 1800 13200 1800 14400 600 14400 600 13200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 1200 14400 1200 15600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 15000 1800 15000
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4200 11700 450 15750
+2 1 0 4 4 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 600 11700 4350 15750
+-6
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 600 1800 600 1800 1800 600 1800 600 600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1800 600 4200 600 4200 3000 1800 3000 1800 600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 4800 600 6000 600 6000 1800 4800 1800 4800 600
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6000 600 8400 600 8400 3000 6000 3000 6000 600
+2 1 0 10 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 360.00 270.00
+	 4500 5100 6300 5100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 600 8100 1800 8100 1800 9300 600 9300 600 8100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 1800 8100 4200 8100 4200 10500 1800 10500 1800 8100
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 12000 10200 12000 10200 14400 7800 14400 7800 12000
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 7800 14400 9000 14400 9000 15600 7800 15600 7800 14400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6600 14400 7800 14400 7800 15600 6600 15600 6600 14400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 6600 13200 7800 13200 7800 14400 6600 14400 6600 13200
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 14400 7200 15600
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6600 15000 7800 15000
+2 1 0 10 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 360.00 270.00
+	 4500 13800 6300 13800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3
+	 7800 13200 9000 13200 9000 14400
+3 0 0 2 0 7 50 0 -1 0.000 0 0 0 4
+	 6150 225 5175 675 4575 1725 4575 3075
+	 0.000 1.000 1.000 0.000
+3 0 0 2 0 7 50 0 -1 0.000 0 0 0 4
+	 1875 7275 2325 8775 2400 10125 1800 11550
+	 0.000 1.000 1.000 0.000
+4 0 0 50 0 0 18 0.0000 4 195 510 975 1275 fluid\001
+4 0 0 50 0 0 18 0.0000 4 195 690 5100 1275 mixed\001
+4 0 0 50 0 0 24 0.0000 4 255 660 2700 1875 fluid\001
+4 0 0 50 0 0 24 0.0000 4 255 660 6900 1875 fluid\001
+4 0 0 50 0 0 12 0.0000 4 180 1320 4725 5475 fl_refine_mixed()\001
+4 0 0 50 0 0 24 0.0000 4 255 930 2550 9375 mixed\001
+4 0 0 50 0 0 18 0.0000 4 195 510 975 8775 fluid\001
+4 0 0 50 0 0 12 0.0000 4 180 1425 4725 14175 ftt_refine_corner()\001
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
new file mode 100644
index 0000000..cf7623b
--- /dev/null
+++ b/doc/manpages/Makefile.am
@@ -0,0 +1,24 @@
+dist_man_MANS = \
+	bat2gts.1 \
+	gerris2D.1 \
+	gerris2D3.1 \
+	gerris3D.1 \
+	gfs2gfs.1 \
+	gfs2oogl2D.1 \
+	gfs2oogl2D3.1 \
+	gfs2oogl3D.1 \
+	gfscompare2D.1 \
+	gfscompare2D3.1 \
+	gfscompare3D.1 \
+	gfs-config.1 \
+	gfs-highlight.1 \
+	gfsjoin.1 \
+	gfsxref.1 \
+	ppm2mpeg.1 \
+	ppmcombine.1 \
+	rsurfacequery.1 \
+	shapes.1 \
+	streamanime.1 \
+	xyz2rsurface.1 \
+	gfsjoin2D.1 \
+	gfsjoin3D.1
diff --git a/doc/manpages/Makefile.in b/doc/manpages/Makefile.in
new file mode 100644
index 0000000..b470d54
--- /dev/null
+++ b/doc/manpages/Makefile.in
@@ -0,0 +1,491 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc/manpages
+DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+man1dir = $(mandir)/man1
+am__installdirs = "$(DESTDIR)$(man1dir)"
+NROFF = nroff
+MANS = $(dist_man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+dist_man_MANS = \
+	bat2gts.1 \
+	gerris2D.1 \
+	gerris2D3.1 \
+	gerris3D.1 \
+	gfs2gfs.1 \
+	gfs2oogl2D.1 \
+	gfs2oogl2D3.1 \
+	gfs2oogl3D.1 \
+	gfscompare2D.1 \
+	gfscompare2D3.1 \
+	gfscompare3D.1 \
+	gfs-config.1 \
+	gfs-highlight.1 \
+	gfsjoin.1 \
+	gfsxref.1 \
+	ppm2mpeg.1 \
+	ppmcombine.1 \
+	rsurfacequery.1 \
+	shapes.1 \
+	streamanime.1 \
+	xyz2rsurface.1 \
+	gfsjoin2D.1 \
+	gfsjoin3D.1
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/manpages/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu doc/manpages/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-man1: $(dist_man_MANS)
+	@$(NORMAL_INSTALL)
+	test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	{ for i in $$list; do echo "$$i"; done; \
+	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	test -z "$$files" || { \
+	  echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
+	  cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@list='$(MANS)'; if test -n "$$list"; then \
+	  list=`for p in $$list; do \
+	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	    if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+	  if test -n "$$list" && \
+	    grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+	    echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+	    grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
+	    echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+	    echo "       typically \`make maintainer-clean' will remove them" >&2; \
+	    exit 1; \
+	  else :; fi; \
+	else :; fi
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(man1dir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-man1 \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am uninstall-man uninstall-man1
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/manpages/bat2gts.1 b/doc/manpages/bat2gts.1
new file mode 100644
index 0000000..68bfaa5
--- /dev/null
+++ b/doc/manpages/bat2gts.1
@@ -0,0 +1,50 @@
+.TH bat2gts 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+bat2gts \- takes a bathymetry file (three columns: longitude, latitude (degree), depth (meters)) and generates a GTS depth file for the given domain.
+
+.SH SYNOPSIS
+.B bat2gts
+.RI [OPTIONS] < BATHY
+.SH DESCRIPTION
+This manual page documents briefly the
+.B bat2gts
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-\-long=V
+Set reference longitude to V (default 174 deg)
+.TP
+.B \-\-lat=V
+Set reference latitude  to V (default \-41 deg)
+.TP
+.B \-\-width=V
+Set domain width (default is 500 km)
+.TP
+.B \-\-depth=V
+Set reference depth to V (default is 5000 meters)
+.TP
+.B \-\-coast=V
+Set coastline reference depth to V (default is 0.1 meters)
+.TP
+.B \-\-rel=T
+Set relative error allowed on bathymetry (default is 0.05)
+.TP
+.B \-\-angle=V
+Rotation of V degrees (default is 0)
+.TP
+.B \-v, \-\-verbose
+Display info about the process
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+bat2gts was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gerris2D.1 b/doc/manpages/gerris2D.1
new file mode 100644
index 0000000..46472bc
--- /dev/null
+++ b/doc/manpages/gerris2D.1
@@ -0,0 +1,53 @@
+.TH gerris 1 "July 9, 2008" "" "User Commands"
+
+.SH NAME
+gerris2D, gerris2D3, gerris3D \- the Gerris flow solver simulation engine.
+
+.SH SYNOPSIS
+.B gerris
+.RI [OPTION] FILE
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gerris
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-s N, \-\-split=N
+Splits the domain N times and returns the corresponding simulation.
+.TP
+.B \-i, \-\-pid
+Keep box pids when splitting. The default is to allocate one pid per box.
+.TP
+.B \-P N, \-\-partition=N
+Partition the domain in 2^N subdomains and returns the corresponding simulation.
+.TP
+.B \-d, \-\-data
+When splitting or partitioning, output all data.
+.TP
+.B \-P, \-\-profile
+Profiles calls to boundary conditions.
+.TP
+.B \-m, \-\-macros
+Turn macros support on.
+.TP
+.B \-DNAME, \-DNAME=VALUE, \-\-define=NAME, \-\-define=NAME=VALUE
+Defines NAME as a macro expanding to VALUE (macro support is implicitly turned on).
+.TP
+.B \-eEV, \-\-event=EV
+Evaluates the GfsEvent EV and returns the simulation.
+.TP
+.B \-V, \-\-version
+Output version information and exit.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gerris was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gerris2D3.1 b/doc/manpages/gerris2D3.1
new file mode 100644
index 0000000..6fe6b25
--- /dev/null
+++ b/doc/manpages/gerris2D3.1
@@ -0,0 +1 @@
+.so man1/gerris2D.1
diff --git a/doc/manpages/gerris3D.1 b/doc/manpages/gerris3D.1
new file mode 100644
index 0000000..6fe6b25
--- /dev/null
+++ b/doc/manpages/gerris3D.1
@@ -0,0 +1 @@
+.so man1/gerris2D.1
diff --git a/doc/manpages/gfs-config.1 b/doc/manpages/gfs-config.1
new file mode 100644
index 0000000..99781c9
--- /dev/null
+++ b/doc/manpages/gfs-config.1
@@ -0,0 +1,35 @@
+.TH gfs-config 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+gfs-config \- defines values for programs using gts.
+
+.SH SYNOPSIS
+.B gfs-config
+.RI [OPTIONS]
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfs-config
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-\-prefix[=DIR]
+.TP
+.B \-\-exec-prefix[=DIR]
+.TP
+.B \-\-version
+.TP
+.B \-\-libs
+.TP
+.B \-\-cflags
+.TP
+.B \-\-2D
+
+.SH AUTHOR
+gfs-config was written by Stephane Popinet <popinet at users.sourceforge.net>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfs-highlight.1 b/doc/manpages/gfs-highlight.1
new file mode 100644
index 0000000..c1025eb
--- /dev/null
+++ b/doc/manpages/gfs-highlight.1
@@ -0,0 +1,32 @@
+.TH gfs-highlight 1 "July 9, 2008" "" "User Commands"
+
+.SH NAME
+gfs-highlight \- syntax highlighting/hypertext linking of Gerris simulation files.
+
+.SH SYNOPSIS
+.B gfs-highlight
+.RI [OPTIONS] < input.gfs > output.html
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfs-highlight
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-\-title=TITLE
+Sets the page title.
+.TP
+.B \-\-css=FILE
+Sets the CSS stylesheet filename.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfs-highlight was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfs2gfs.1 b/doc/manpages/gfs2gfs.1
new file mode 100644
index 0000000..6962516
--- /dev/null
+++ b/doc/manpages/gfs2gfs.1
@@ -0,0 +1,26 @@
+.TH gfs2gfs 1 "July 9, 2008" "" "User Commands"
+
+.SH NAME
+gfs2gfs \- converts old Gerris simulation files to the current format.
+
+.SH SYNOPSIS
+.B gfs2gfs
+.RI [OPTIONS] < OLDFILE > NEWFILE
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfs2gfs
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfs2gfs was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfs2oogl2D.1 b/doc/manpages/gfs2oogl2D.1
new file mode 100644
index 0000000..1b23e63
--- /dev/null
+++ b/doc/manpages/gfs2oogl2D.1
@@ -0,0 +1,105 @@
+.TH gfs2oogl 1 "July 9, 2008" "" "User Commands"
+
+.SH NAME
+gfs2oogl2D, gfs2oogl2D3, gfs2oogl3D \- converts a Gerris simulation file to other (graphical) formats.
+
+.SH SYNOPSIS
+.B gfs2oogl
+.RI [OPTION] < GFS_FILE
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfs2oogl
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+
+.TP
+.B \-u V, \-\-iso=V
+Outputs a GTS file isosurface for value V the variable needs to be specified using \-c.
+.TP
+.B \-f D, \-\-stream=D
+Draw evenly-spaced streamlines (D is the spacing).
+.TP
+.B \-I M, \-\-dmin=M
+Controls length of evenly-spaced streamlines default is 0.5.
+.TP
+.B \-O M, \-\-maxcost=M
+Controls compression of streamlines (default is 2e-7).
+.TP
+.B \-b x,.., \-\-box=x,y,..
+Specify bounding box for streamline calculation.
+.TP
+.B \-j, \-\-closed
+Outputs only closed streamlines.
+.TP
+.B \-p F, \-\-profile=F
+Output list of values for coordinates defined in F.
+.TP
+.B \-o, \-\-mixed
+Output text values in mixed cells only.
+.TP
+.B \-L L, \-\-level=L
+Use cells at level L only.
+.TP
+.B \-i, \-\-reinit
+Reinitializes refinement and solid fractions.
+.TP
+.B \-e, \-\-merged
+Draw boundaries of merged cells.
+.TP
+.B \-S, \-\-squares
+Draw (colored) squares.
+.TP
+.B \-g, \-\-gnuplot
+Output gnuplot data.
+.TP
+.B \-x VAL, \-\-sx=VAL
+outputs a GTS surface, cross section for x = VAL of the scalar variable.
+.TP
+.B \-y VAL, \-\-sy=VAL
+outputs a GTS surface, cross section for y = VAL of the scalar variable.
+.TP
+.B \-z VAL, \-\-sz=VAL
+outputs a GTS surface, cross section for z = VAL of the scalar variable.
+.TP
+.B \-s S, \-\-surface=S
+outputs the surface defined by file S (or the solid surface is S is equal to `solid').
+.TP
+.B \-V S, \-\-vector=S
+output an OOGL representation of the velocity vector field in the mixed cells.
+.TP
+.B \-l F, \-\-streamlines=F
+draw streamlines starting from each point defined in file F.
+.TP
+.B \-C F, \-\-cylinder=F
+draw stream cylinders starting from each point defined in file F.
+.TP
+.B \-R F, \-\-ribbon=F
+draw stream ribbons starting from each point defined in file F.
+.TP
+.B \-r
+refines the solid surface according to the local resolution.
+.TP
+.B \-c V, \-\-color=V
+color surfaces, streamlines etc... according to the.
+.TP
+.B \-m V, \-\-min=V
+set minimum scalar value to V.
+.TP
+.B \-M V, \-\-max=V
+set maximum scalar value to V.
+.TP
+.B \-v, \-\-verbose
+display statistics and other info.
+.TP
+.B \-h, \-\-help
+display the help and exit.
+
+.SH AUTHOR
+gfs2oogl was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfs2oogl2D3.1 b/doc/manpages/gfs2oogl2D3.1
new file mode 100644
index 0000000..676f9cf
--- /dev/null
+++ b/doc/manpages/gfs2oogl2D3.1
@@ -0,0 +1 @@
+.so man1/gfs2oogl2D.1
diff --git a/doc/manpages/gfs2oogl3D.1 b/doc/manpages/gfs2oogl3D.1
new file mode 100644
index 0000000..676f9cf
--- /dev/null
+++ b/doc/manpages/gfs2oogl3D.1
@@ -0,0 +1 @@
+.so man1/gfs2oogl2D.1
diff --git a/doc/manpages/gfscompare2D.1 b/doc/manpages/gfscompare2D.1
new file mode 100644
index 0000000..3682236
--- /dev/null
+++ b/doc/manpages/gfscompare2D.1
@@ -0,0 +1,84 @@
+.TH gfscompare 1 "July 10, 2008" "" "User Commands"
+
+.SH NAME
+gfscompare2D, gfscompare2D3, gfscompare3D \- computes the difference between the solutions in FILE1 and FILE2 for variable VAR.
+
+.SH SYNOPSIS
+.B gfscompare
+.RI [OPTION] FILE
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfscompare
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+
+.TP
+.B \-x, \-\-mixed
+Compute error only in mixed cells.
+.TP
+.B \-m V, \-\-min=V
+Set minimum of color scale to V (used with \-S).
+.TP
+.B \-M V, \-\-max=V
+Set maximum of color scale to V.
+.TP
+.B \-a, \-\-abs
+Output the absolute value of the error field.
+.TP
+.B \-C, \-\-constant
+Apply a constant shift to one of the field, minimizing the error between the two fields (useful for pressure).
+.TP
+.B \-w, \-\-not-weighted
+Do not use area-weighted norm estimation.
+.TP
+.B \-c, \-\-centered
+Use error estimation for cell-centered variables.
+.TP
+.B \-p P, \-\-period=P
+Shifts FILE1 by P along the x axis.
+.TP
+.B \-H, \-\-histogram
+Output (error,volume) pairs for each cell used to compute the error norms.
+.TP
+.B \-o, \-\-output
+Output a GTS representation of the error field.
+.TP
+.B \-S, \-\-squares
+Output an OOGL representation of the error field.
+.TP
+.B \-G, \-\-gnuplot
+Output a gnuplot representation of the error field.
+.TP
+.B \-t, \-\-triangulate
+Use center of mass triangulation.
+.TP
+.B \-l, \-\-log
+Output the log10 of the absolute value of the error field.
+.TP
+.B \-f L, \-\-full=L
+Compare only leaf cells descendants of a cell full at level L or all full leaf cells if L = \-1.
+.TP
+.B \-r, \-\-refined
+Display error norm on the finest grid.
+.TP
+.B \-n, \-\-nocheck
+Do not check solid fractions.
+.TP
+.B \-g C, \-\-gradient=C
+Use the C component of the gradient of VAR.
+.TP
+.B \-v, \-\-verbose
+Display difference statistics and other info.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfscompare was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfscompare2D3.1 b/doc/manpages/gfscompare2D3.1
new file mode 100644
index 0000000..e4143ea
--- /dev/null
+++ b/doc/manpages/gfscompare2D3.1
@@ -0,0 +1 @@
+.so man1/gfscompare2D.1
diff --git a/doc/manpages/gfscompare3D.1 b/doc/manpages/gfscompare3D.1
new file mode 100644
index 0000000..e4143ea
--- /dev/null
+++ b/doc/manpages/gfscompare3D.1
@@ -0,0 +1 @@
+.so man1/gfscompare2D.1
diff --git a/doc/manpages/gfsjoin.1 b/doc/manpages/gfsjoin.1
new file mode 100644
index 0000000..bef5de0
--- /dev/null
+++ b/doc/manpages/gfsjoin.1
@@ -0,0 +1,25 @@
+.TH gfsjoin 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+gfsjoin \- joins Gerris files.
+
+.SH SYNOPSIS
+.B gfsjoin
+.RI Simfile Directory Rootname NP Tailname > Joined
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfsjoin
+command.
+
+.SH OPTIONS
+Simfile:        Name of the simulation file
+Directory:      Directory where results are located
+Rootname:       File root name
+NP:             Number of processors
+Tailname:       File tail name
+
+.SH AUTHOR
+gfsjoin was written by Daniel Fuster.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/gfsjoin2D.1 b/doc/manpages/gfsjoin2D.1
new file mode 100644
index 0000000..3dfb56d
--- /dev/null
+++ b/doc/manpages/gfsjoin2D.1
@@ -0,0 +1,29 @@
+.TH gfsjoin 1 "June 19, 2009" "" "User Commands"
+
+.SH NAME
+gfsjoin2D, gfsjoin3D \- joins several parallel Gerris simulation files
+
+.SH SYNOPSIS
+.B gfsjoin
+[OPTIONS] FILE1 FILE2 ... > JOINED
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfsjoin
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-k, \-\-keep
+Keep MPI boundaries.
+.TP
+.B \-v, \-\-verbose
+Display statistics and other info.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfsjoin was written by Stephane Popinet <s.popinet at niwa.co.nz>.
diff --git a/doc/manpages/gfsjoin3D.1 b/doc/manpages/gfsjoin3D.1
new file mode 100644
index 0000000..3dfb56d
--- /dev/null
+++ b/doc/manpages/gfsjoin3D.1
@@ -0,0 +1,29 @@
+.TH gfsjoin 1 "June 19, 2009" "" "User Commands"
+
+.SH NAME
+gfsjoin2D, gfsjoin3D \- joins several parallel Gerris simulation files
+
+.SH SYNOPSIS
+.B gfsjoin
+[OPTIONS] FILE1 FILE2 ... > JOINED
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfsjoin
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-k, \-\-keep
+Keep MPI boundaries.
+.TP
+.B \-v, \-\-verbose
+Display statistics and other info.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfsjoin was written by Stephane Popinet <s.popinet at niwa.co.nz>.
diff --git a/doc/manpages/gfsxref.1 b/doc/manpages/gfsxref.1
new file mode 100644
index 0000000..61c1e61
--- /dev/null
+++ b/doc/manpages/gfsxref.1
@@ -0,0 +1,29 @@
+.TH gfsxref 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+gfsxref \- creates cross-references for occurences of KEYWORD in input.gfs
+
+.SH SYNOPSIS
+.B gfsxref
+.RI [OPTIONS] KEYWORD < input.gfs > output.html
+.SH DESCRIPTION
+This manual page documents briefly the
+.B gfsxref
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-\-url=URL
+Reference URL for input.gfs.
+.TP
+.B \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+gfsxref was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/ppm2mpeg.1 b/doc/manpages/ppm2mpeg.1
new file mode 100644
index 0000000..6fe6b25
--- /dev/null
+++ b/doc/manpages/ppm2mpeg.1
@@ -0,0 +1 @@
+.so man1/gerris2D.1
diff --git a/doc/manpages/ppmcombine.1 b/doc/manpages/ppmcombine.1
new file mode 100644
index 0000000..938c360
--- /dev/null
+++ b/doc/manpages/ppmcombine.1
@@ -0,0 +1,29 @@
+.TH ppmcombine 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+ppmcombine \- combines several PPM files produced by a parallel run of Gerris.
+
+.SH SYNOPSIS
+.B ppmcombine
+.RI [OPTIONS] KEYWORD < input.gfs > output.html
+.SH DESCRIPTION
+This manual page documents briefly the
+.B ppmcombine
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-v, \-\-url=URL
+Display statistics and other info
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+ppmcombine was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/rsurfacequery.1 b/doc/manpages/rsurfacequery.1
new file mode 100644
index 0000000..6fe6b25
--- /dev/null
+++ b/doc/manpages/rsurfacequery.1
@@ -0,0 +1 @@
+.so man1/gerris2D.1
diff --git a/doc/manpages/shapes.1 b/doc/manpages/shapes.1
new file mode 100644
index 0000000..56b9305
--- /dev/null
+++ b/doc/manpages/shapes.1
@@ -0,0 +1,48 @@
+.TH shapes 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+shapes \- generates various shapes for Gerris.
+
+.SH SYNOPSIS
+.B shapes
+.RI [OPTIONS] SHAPE
+.PP
+SHAPE can be one of: ellipse, star, 4ellipses, square, almgren, channel, 
+half-cylinder, rayleigh-taylor, FILE.
+
+.SH DESCRIPTION
+This manual page documents briefly the
+.B shapes
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-z, \-\-zextrude
+Shape file contains z coordinate.
+.TP
+.B \-n N, \-\-number=N
+Set number of points for polar surfaces (default is 100).
+.TP
+.B \-o, \-\-open
+Generate open surfaces.
+.TP
+.B \-d R, \-\-dr=R
+Set inner radius for star to R (default is 0.15).
+.TP
+.B \-r R, \-\-ratio=R
+Ratio x/y of the ellipse (default is 1).
+.TP
+.B \-v, \-\-url=URL
+Display surface statistics.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+shapes was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/manpages/streamanime.1 b/doc/manpages/streamanime.1
new file mode 100644
index 0000000..6fe6b25
--- /dev/null
+++ b/doc/manpages/streamanime.1
@@ -0,0 +1 @@
+.so man1/gerris2D.1
diff --git a/doc/manpages/xyz2rsurface.1 b/doc/manpages/xyz2rsurface.1
new file mode 100644
index 0000000..1737fdc
--- /dev/null
+++ b/doc/manpages/xyz2rsurface.1
@@ -0,0 +1,32 @@
+.TH xyz2rsurface 1 "August 9, 2008" "" "User Commands"
+
+.SH NAME
+xyz2rsurface \- converts the x, y and z coordinates on standard input to an R*-tree-indexed database suitable for use with the GfsRefineTerrain object of Gerris.
+
+.SH SYNOPSIS
+.B xyz2rsurface
+.RI [OPTION] BASENAME
+.SH DESCRIPTION
+This manual page documents briefly the
+.B xyz2rsurface
+command.
+
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-p N  \-\-pagesize=N
+Sets the pagesize in bytes (default is 4096)
+.TP
+.B \-v, \-\-verbose
+Display progress bar.
+.TP
+.B \-h, \-\-help
+Display the help and exit.
+
+.SH AUTHOR
+xyz2rsurface was written by Stephane Popinet <s.popinet at niwa.co.nz>.
+.PP
+This manual page was written by Ruben Molina <rmolina at udea.edu.co>,
+for the Debian project (but may be used by others).
diff --git a/doc/share/contents.png b/doc/share/contents.png
new file mode 100644
index 0000000..37a5231
Binary files /dev/null and b/doc/share/contents.png differ
diff --git a/doc/share/darcs.css b/doc/share/darcs.css
new file mode 100644
index 0000000..a1da05f
--- /dev/null
+++ b/doc/share/darcs.css
@@ -0,0 +1,115 @@
+BODY {
+  font: x-small sans-serif;
+  font-size: 14px;
+  background: white;
+  color: black;
+  margin: 0;
+  padding: 1em;
+}
+
+A {
+  text-decoration: none;
+  color: #002bb8;
+  background: none;
+  border-style: none;
+}
+
+A:visited {
+  color: #5a3696;
+}
+
+A:active {
+  color: #faa700;
+}
+
+A:hover {
+  text-decoration: underline;
+}
+
+.section a {
+  color: black;
+  text-decoration: none;
+}
+
+.subsection a {
+  color: black;
+  text-decoration: none;
+}
+
+.subsubsection a {
+  color: black;
+  text-decoration: none;
+}
+
+A IMG {border: none; }
+
+PRE     {
+  background: #eeeeee;
+  border: 1px solid #888888;
+  color: black;
+  padding: 1em;
+  white-space: pre;
+}
+
+H1, H2, H3, H4 {
+  color: black;
+}
+
+H1      {
+  font-size: 24px ;
+}
+
+H2      {
+  font-size: 18px;
+}
+
+H3      {
+  font-size: 16px;
+}
+
+H4      {
+  font-size: 14px;
+}
+
+/* GFS parameter files */
+
+.gfs .comment {
+    color: #17A729;
+}
+
+/* headers for darcs command options */
+.cmd-opt-hdr     {
+  color: #494a82;
+  font-size: 14px;
+  font-weight: bold;
+}
+
+/* begin styles for RSS Feed This is the most basic style to use for a list with no bullets */
+
+.rss_title, rss_title a {
+    margin: 0px 0;
+    padding: 0;
+}
+
+.rss_items {
+       list-style:none;
+       margin:0;
+       padding:0;
+}
+
+.rss_item  {
+/*  font-size: x-small; */
+  margin-bottom: 1em;;
+}
+
+.rss_item a:link, .rss_item a:visited, .rss_item a:active {
+
+    }
+
+.rss_item a:hover { 
+
+    }
+    
+.rss_date {
+    font-size: xx-small;
+    }
diff --git a/doc/share/fixnav.sh b/doc/share/fixnav.sh
new file mode 100644
index 0000000..e5b8568
--- /dev/null
+++ b/doc/share/fixnav.sh
@@ -0,0 +1,7 @@
+for f in $1/*.html; do
+    sed 's/contents_motif.gif/contents.png/g' < $f | \
+    sed 's/next_motif.gif/next.png/g' | \
+    sed 's/previous_motif.gif/prev.png/g' \
+    > $f.bak
+    mv -f $f.bak $f
+done
diff --git a/doc/share/next.png b/doc/share/next.png
new file mode 100644
index 0000000..64e126b
Binary files /dev/null and b/doc/share/next.png differ
diff --git a/doc/share/prev.png b/doc/share/prev.png
new file mode 100644
index 0000000..3e8f12f
Binary files /dev/null and b/doc/share/prev.png differ
diff --git a/doc/share/up.png b/doc/share/up.png
new file mode 100644
index 0000000..2db1ce6
Binary files /dev/null and b/doc/share/up.png differ
diff --git a/doc/tutorial/Makefile.am b/doc/tutorial/Makefile.am
new file mode 100644
index 0000000..9f52911
--- /dev/null
+++ b/doc/tutorial/Makefile.am
@@ -0,0 +1,77 @@
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = tutorial.tex depend.awk
+
+Makefile.deps: Makefile.am tutorial.tex
+	awk -f depend.awk file="tutorial" < tutorial.tex > Makefile.deps
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out \
+	boundaries.pdf direction.eps direction.pdf dxscreen.eps dxscreen.pdf \
+	gfs2oogl.pdf half-cylinder.eps half-cylinder.pdf refined1.pdf refined1_cells.pdf \
+	refined2.pdf vorticity.eps vorticity.pdf gfsview.eps tutorial1.tex \
+	Makefile.deps
+
+tutorial.tar.gz: tutorial1.dvi
+	rm -r -f tutorial
+	sed 's/input{pdf.tex}/usepackage{graphicx}\\newcommand{\\gfx}{eps}/g' < tutorial.tex | sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > tutorial1.tex
+	hevea -fix tutorial1.tex
+	imagen -res 600 -extra "pnmscale 0.24" tutorial1
+	mkdir tutorial
+	mv -f tutorial1[0-9][0-9][0-9].png tutorial
+##	fixme: the character conversion below is a workaround for a bug in hevea version < 1.09
+	konwert iso1-utf8 < tutorial1.html > tutorial/tutorial1.html
+	cp ../share/darcs.css tutorial/tutorial.css
+	rm -f tutorial1.h{tml,aux,ind,toc} tutorial1.image.tex
+	tar cf tutorial.tar tutorial
+	gzip -f --best tutorial.tar
+
+tutorial1.dvi: tutorial.tex Makefile.deps
+	sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" < tutorial.tex | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > tutorial1.tex
+	latex -interaction=nonstopmode tutorial1.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tutorial1.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tutorial1.tex
+
+tutorial.pdf: tutorial1.dvi
+	dvips -Ppdf -G0 tutorial1.dvi -o tutorial1.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true tutorial1.ps tutorial.pdf
+	rm -f tutorial1.ps
+
+%.eps: %.xmgr
+	/usr/local/grace/bin/xmgrace -noask -hardcopy -hdevice EPS -printfile $@ $<
+
+%.eps: %.agr
+	/usr/local/grace/bin/xmgrace -noask -hardcopy -hdevice EPS -printfile $@ $<
+
+%.eps: %.fig
+	fig2dev -L ps $< > $@ ; sh epsbbox.sh $@ 
+
+%.eps: %.jpeg
+	convert $< $@.gif
+	convert $@.gif EPS:$@
+	- rm -f $@.gif
+
+%.eps: %.jpg
+	convert $< $@.gif
+	convert $@.gif EPS:$@
+	- rm -f $@.gif
+
+%.eps: %.gif
+	convert $< EPS:$@
+
+%.eps: %.png
+	convert $< EPS:$@
+
+%.pdf: %.jpg
+	convert $< EPDF:$@
+
+%.pdf: %.png
+	convert $< EPDF:$@
+
+%.pdf: %.epsf
+	epstopdf $<
+
+%.pdf: %.eps
+	epstopdf $<
+
+-include Makefile.deps
diff --git a/doc/tutorial/Makefile.in b/doc/tutorial/Makefile.in
new file mode 100644
index 0000000..8be1549
--- /dev/null
+++ b/doc/tutorial/Makefile.in
@@ -0,0 +1,455 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc/tutorial
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+EXTRA_DIST = tutorial.tex depend.awk
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/tutorial/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu doc/tutorial/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+Makefile.deps: Makefile.am tutorial.tex
+	awk -f depend.awk file="tutorial" < tutorial.tex > Makefile.deps
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out \
+	boundaries.pdf direction.eps direction.pdf dxscreen.eps dxscreen.pdf \
+	gfs2oogl.pdf half-cylinder.eps half-cylinder.pdf refined1.pdf refined1_cells.pdf \
+	refined2.pdf vorticity.eps vorticity.pdf gfsview.eps tutorial1.tex \
+	Makefile.deps
+
+tutorial.tar.gz: tutorial1.dvi
+	rm -r -f tutorial
+	sed 's/input{pdf.tex}/usepackage{graphicx}\\newcommand{\\gfx}{eps}/g' < tutorial.tex | sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > tutorial1.tex
+	hevea -fix tutorial1.tex
+	imagen -res 600 -extra "pnmscale 0.24" tutorial1
+	mkdir tutorial
+	mv -f tutorial1[0-9][0-9][0-9].png tutorial
+	konwert iso1-utf8 < tutorial1.html > tutorial/tutorial1.html
+	cp ../share/darcs.css tutorial/tutorial.css
+	rm -f tutorial1.h{tml,aux,ind,toc} tutorial1.image.tex
+	tar cf tutorial.tar tutorial
+	gzip -f --best tutorial.tar
+
+tutorial1.dvi: tutorial.tex Makefile.deps
+	sed "s/GFS_VERSION/`$(top_srcdir)/src/gerris2D -V 2>&1 | awk '{ if ($$5 == "version") print $$6}'`/g" < tutorial.tex | sed 's/\\today/'"`date +\"%B %e, %Y\"`/g" > tutorial1.tex
+	latex -interaction=nonstopmode tutorial1.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tutorial1.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tutorial1.tex
+
+tutorial.pdf: tutorial1.dvi
+	dvips -Ppdf -G0 tutorial1.dvi -o tutorial1.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true tutorial1.ps tutorial.pdf
+	rm -f tutorial1.ps
+
+%.eps: %.xmgr
+	/usr/local/grace/bin/xmgrace -noask -hardcopy -hdevice EPS -printfile $@ $<
+
+%.eps: %.agr
+	/usr/local/grace/bin/xmgrace -noask -hardcopy -hdevice EPS -printfile $@ $<
+
+%.eps: %.fig
+	fig2dev -L ps $< > $@ ; sh epsbbox.sh $@ 
+
+%.eps: %.jpeg
+	convert $< $@.gif
+	convert $@.gif EPS:$@
+	- rm -f $@.gif
+
+%.eps: %.jpg
+	convert $< $@.gif
+	convert $@.gif EPS:$@
+	- rm -f $@.gif
+
+%.eps: %.gif
+	convert $< EPS:$@
+
+%.eps: %.png
+	convert $< EPS:$@
+
+%.pdf: %.jpg
+	convert $< EPDF:$@
+
+%.pdf: %.png
+	convert $< EPDF:$@
+
+%.pdf: %.epsf
+	epstopdf $<
+
+%.pdf: %.eps
+	epstopdf $<
+
+-include Makefile.deps
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/tutorial/depend.awk b/doc/tutorial/depend.awk
new file mode 100644
index 0000000..ed7e187
--- /dev/null
+++ b/doc/tutorial/depend.awk
@@ -0,0 +1,20 @@
+BEGIN {
+  FS = "{|=|}| |[|]";
+}
+{
+  if ($1 == "\\psfig" && $2 == "file")
+    depeps = depeps " " $3;
+  else if ($1 == "\\includegraphics[width" ||
+	   $1 == "\\includegraphics[height" ||
+	   $1 == "\\includegraphics[angle" ||
+           $1 == "\\includegraphics*[width" ||
+	   $1 == "\\includegraphics*[height" ||
+	   $1 == "\\includegraphics*[angle") {
+    for (i = 2; i <= NF; i++)
+      if (match ($i, "eps"))
+	depeps = depeps " " $i;
+  }
+}
+END {
+  print file "1.dvi: " depeps;
+}
diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex
new file mode 100644
index 0000000..4f6cc7f
--- /dev/null
+++ b/doc/tutorial/tutorial.tex
@@ -0,0 +1,1295 @@
+\documentclass[a4paper]{article}
+\usepackage{hevea}
+\usepackage{color}
+\usepackage{graphicx}
+
+\oddsidemargin=4mm
+\evensidemargin=-1mm
+\topmargin=-7mm
+\textwidth=15.42cm
+\textheight=23.2cm
+
+\newcommand{\gfsweb}{http://gfs.sf.net}
+\newcommand{\htmladdnormallinkfoot}[2]{\footahref{#2}{#1}}
+\newcommand{\htmladdnormallink}[2]{\ahref{#2}{#1}}
+\loadcssfile{tutorial.css}
+
+\title{Gerris tutorial}
+
+\begin{document}
+
+\mbox{}\vspace{1cm}
+\begin{center}
+{\huge The Gerris Tutorial}\\
+{\large Version GFS_VERSION}\\
+\vspace{5mm}
+{\large St\'ephane Popinet\\
+{\tt popinet at users.sf.net}\\
+\vspace{5mm}
+\today}
+\vspace{1cm}
+\end{center}
+
+\tableofcontents 
+
+\section{Introduction}
+
+This tutorial is a step-by-step introduction to the different concepts
+necessary to use Gerris. It is specifically designed for a end-user
+and is not a technical description of the numerical techniques used
+within Gerris. If you are interested by that, you should consult the
+bibliography section on the \htmladdnormallinkfoot{Gerris web
+site}{\gfsweb}.
+
+Various versions of this tutorial are available:
+\begin{itemize}
+\item Printable format: \htmladdnormallinkfoot{PDF}{\gfsweb/tutorial/tutorial.pdf}.
+\item HTML: \htmladdnormallinkfoot{direct link}{\gfsweb/tutorial/tutorial/tutorial1.html} or
+\htmladdnormallinkfoot{compressed archive}{\gfsweb/tutorial/tutorial.tar.gz}.
+\end{itemize}
+
+In this tutorial I will assume that you are familiar with the Unix
+shell (and that you are running some version of a Unix system). Some
+knowledge of C programming would also be very helpful if you intend to 
+extend Gerris with your own objects.
+
+If Gerris is not already installed on your system, have a look at the
+\htmladdnormallinkfoot{installation
+  instructions}{\gfsweb/wiki/index.php/Installation\_summary} on the
+Gerris web site.
+
+We are now ready to start. Just to check that everything is okay try:
+\begin{verbatim}
+% gerris2D -V
+\end{verbatim}
+
+\subsection{Simulation file}
+
+Gerris is a console-based program. It takes a {\em parameter} or {\em
+simulation} file as input and produces various types of files as output.
+Everything needed to run the simulation is specified in the parameter
+file, this includes:
+\begin{itemize}
+\item Layout of the simulation domain
+\item Initial conditions
+\item Boundary conditions
+\item Solid boundaries
+\item What to output (and when)
+\item Control parameters for the numerical schemes
+\end{itemize}
+
+\section{A simple simulation file}
+
+In this section we will see how to write a simulation file for the
+{\em initial random vorticity} example in the Gerris web site
+gallery. First of all, it is always a good idea to run simulations in
+their own directory. Type this at your shell prompt:
+\begin{verbatim}
+% mkdir vorticity
+% cd vorticity
+\end{verbatim}
+As a starting point we will use the following simulation file: {\tt
+vorticity.gfs}
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 0 }
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+This is a valid simulation file but it does not do much as you can see 
+by typing
+\begin{verbatim}
+% gerris2D vorticity.gfs
+\end{verbatim}
+It is a good starting point however to explain the general structure
+of a simulation file.
+
+\subsection{A few comments on syntax}
+
+First of all, there are two types of parameters in a simulation file:
+{\em compulsory} and {\em optional} parameters. Optional parameters
+are always specified within a {\em braced} block (i.e. a block of text 
+delimited by braces ({\tt \{ like this \}}). They also often take the form
+\begin{verbatim}
+parameter = value
+\end{verbatim}
+where {\tt parameter} is an unique identifier (within this braced
+block). All the other parameters are compulsory parameters.
+For example, in {\tt vorticity.gfs} both
+\begin{verbatim}
+  GfsTime { end = 0 }
+\end{verbatim}
+and
+\begin{verbatim}
+end = 0
+\end{verbatim}
+are optional parameters.
+
+The second important syntax point regards the way various fields are
+delimited. Newline (or ``carriage return'') characters are generally used to
+delimitate different ``objects'' in the simulation file. The only
+case where this rule does not apply is within braced blocks defining
+optional arguments of the form
+\begin{verbatim}
+parameter = value
+\end{verbatim}
+For example, in {\tt vorticity.gfs} the following blocks of text are
+all objects:
+\begin{itemize}
+\item
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 0 }
+}
+\end{verbatim}
+\item
+\begin{verbatim}
+  GfsTime { end = 0 }
+\end{verbatim}
+\item
+\begin{verbatim}
+GfsBox {}
+\end{verbatim}
+\item
+\begin{verbatim}
+1 1 right
+\end{verbatim}
+\item
+\begin{verbatim}
+1 1 top
+\end{verbatim}
+\end{itemize}
+Following this rule, {\tt vorticty.gfs} could have been written
+equivalently as:
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} { GfsTime {
+  end = 0 }
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+
+\subsection{Topology description of the simulation domain}
+
+Ok, so what are all these ``objects'' for?  The first line of the
+simulation file defines a {\em graph} representing the general layout
+of the simulation domain and follows this syntax:
+\begin{description}
+\item[1st field] number of nodes in the graph ({\tt 1})
+\item[2nd field] number of edges connecting the nodes ({\tt 2})
+\item[3rd field] object type for the graph ({\tt GfsSimulation})
+\item[4th field] default object type for the nodes ({\tt GfsBox})
+\item[5th field] object type for the edges ({\tt GfsGEdge})
+\item[6th field] 1st optional parameters (braced block)
+\item[7th field] 2nd optional parameters (braced block)
+\end{description}
+We then jump to the end of the 2nd optional parameters to line
+\begin{verbatim}
+GfsBox {}
+\end{verbatim}
+which describes the first (and unique in this case) node of the
+graph. The first field is the object type of the node ({\tt GfsBox}),
+the second field contains optional parameters.
+The following two lines 
+\begin{verbatim}
+1 1 right
+1 1 top
+\end{verbatim}
+define the edges of the graph as follows:
+\begin{description}
+\item[1st field] index of the starting node ({\tt 1})
+\item[2nd field] index of the ending node   ({\tt 1})
+\item[3rd field] spatial direction in which the two nodes are
+connected ({\tt right} and {\tt top})
+\end{description}
+The nodes are always indexed starting from one. The spatial directions 
+are defined on figure \ref{direction}.
+From this, we see that this file defines a simulation domain
+containing one node (a {\tt GfsBox}) connected with itself in both the
+horizontal ({\tt right}) and vertical ({\tt top}) directions.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[width=0.4\hsize]{direction.eps}
+\end{center}
+\caption{Definition of spatial directions}
+\label{direction}
+\end{figure}
+By default, a {\tt GfsBox} is a square (in 2D) or a cube (in 3D) of
+size unity. The first node of the graph is always centered on the
+origin and is used as the reference to position the other nodes.  We
+have consequently defined a square simulation domain of size unity,
+centered on the origin and using periodic boundary conditions.
+
+\subsection{Controlling the simulation}
+
+Now that we have defined the simulation domain and the boundary
+conditions, we need to specify the initial conditions, numerical
+schemes parameters and so on. This is all done within the second
+optional parameters block of the graph definition.
+
+In our file we have for the moment only one object in this block:
+\begin{verbatim}
+  GfsTime { end = 0 }
+\end{verbatim}
+As its name indicate, this object defines the physical and the
+computational time. By ``computational time'' I mean the number of
+time steps performed. By default both the physical time and the time
+step number are zero when the program starts. It is possible to set
+different values using for example
+\begin{verbatim}
+  GfsTime { t = 1.4 i = 32 end = 0 }
+\end{verbatim}
+where {\tt i} is the time step number and {\tt t} is the physical
+time. The {\tt end} identifier specifies that the simulation should
+stop when the physical time reaches the given value. It is also
+possible to stop the simulation when a specified number of time steps
+is reached, using the {\tt iend} identifier. If both {\tt end} and
+{\tt iend} are specified, the simulation stops when either of these
+are reached. By default, both {\tt end} and {\tt iend} values are
+infinite.
+
+Ok, let's then change this object to
+\begin{verbatim}
+  GfsTime { end = 50 }
+\end{verbatim}
+
+\subsubsection{Spatial discretisation}
+
+The next step is to specify what spatial resolution we want for the
+discretisation. For the moment, the only thing we have defined is the
+root of the quad/octree. The whole domain is thus discretised with
+only one grid point\dots
+
+We need to specify how we want to refine this initial root cell. This
+is done by using an {\tt GfsRefine} object. We can do this by adding
+the line
+\begin{verbatim}
+  GfsRefine 6
+\end{verbatim}
+to the second optional parameter block. This is the simplest possible
+way to refine the initial root cell. We tell the program that we want
+to keep refining the cell tree (by dividing each cell in four children
+cells (in 2D, eight in 3D)) until the {\em level} of the cell is equal
+to five. The level of the root cell is zero, the level of all its
+children cells is one and so on recursively. After this refinement
+process completes we have created a regular Cartesian grid with
+$2^6=64$ cells in each dimension on the finest level ($6$).
+
+\subsubsection{Initial conditions}
+
+We now need to specify the initial conditions and the various actions
+(such as writing results, information messages etc\dots) we want to
+perform when the simulation is running. All these things are treated
+by Gerris as various types of {\em events}, all represented by objects
+derived from the same parent object {\tt GfsEvent}.
+
+Initial conditions are a particular type of event happening only once
+and before any other type of event, they are all derived from the same 
+parent object {\tt GfsInit}.
+
+Gerris comes with a few different objects describing various initial
+conditions. As there is no way Gerris could provide all the different
+initial conditions users could think of, Gerris makes it easy for
+users to create their own initialisation objects by extending the {\tt
+GfsInit} object class. In order not to have to recompile (or more
+exactly re-link) the whole code everytime a new class is added, Gerris
+uses dynamically linked {\em modules} which can be loaded at
+runtime. We will see later how to write your own modules. 
+
+For the moment, we will use the default {\tt GfsInit} object. Just add
+the following lines to {\tt vorticity.gfs}:
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 50 }
+  GfsRefine 6
+  GfsInit {} {
+    U = (0.5 - rand()/(double)RAND_MAX)
+    V = (0.5 - rand()/(double)RAND_MAX)
+  }
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+Using {\tt GfsInit} it is possible to set the initial value of each of
+the simulation variables. By default all variables are set to zero
+initially. In our case we tell Gerris to define the two components of
+the velocity field {\tt U} and {\tt V} as C functions. The standard
+{\tt rand{}} function of the C library returns a (pseudo)-random
+number between 0 and {\tt RAND\_MAX}. The two functions we defined
+thus set the components of the velocities in each cell as random
+numbers between -0.5 and 0.5.
+
+This is a powerful feature of the parameter file. In most cases where Gerris requires a number (such as the {\tt GfsRefine 6} line, a function of space and time can be used instead. For example, a valid parameter file could include:
+\begin{verbatim}
+...
+  GfsRefine 6.*(1. - sqrt (x*x + y*y))
+...
+\end{verbatim}
+which would define a mesh refined in concentric circles.
+
+Using this feature, it is possible to define most initial conditions directly in the parameter file.
+
+\subsubsection{Writing results}
+
+The {\tt vorticity.gfs} file we have now is all Gerris needs to run the
+simulation. However, for this run to be any use, we need to specify
+how and when to output the results. This is done by using another
+class of objects: {\tt GfsOutput}, derived from {\tt GfsEvent}. Gerris
+comes with a number of these objects allowing to output various
+aspects of the simulation.
+
+The general syntax for an {\tt GfsEvent} object is as follows:
+\begin{verbatim}
+GfsEvent {
+          start = 0.5 step = 1e-2 end = 3.4
+          istart = 10 iend = 46
+        }
+\end{verbatim}
+this defines an event:
+\begin{itemize}
+\item starting whenever the physical time is larger
+than (or equal to) 0.5 or the time step number is larger than (or
+equal to) 10,
+\item ending whenever the physical time is strictly larger than 3.4 or 
+the time step number is strictly larger than 46,
+\item and occurring every $10^{-2}$ physical time units.
+\end{itemize}
+It is also possible to specify an event step as a number of time steps 
+using the {\tt istep} identifier. Note, however, that you cannot
+specify both {\tt step} and {\tt istep} for the same event. By
+default, {\tt start} and {\tt istart} are zero and {\tt end}, {\tt
+iend}, {\tt step} and {\tt istep} are infinite.
+
+An {\tt GfsOutput} object is derived from {\tt GfsEvent} and follows this 
+syntax:
+\begin{verbatim}
+GfsOutput {} filename-%d-%f-%ld
+\end{verbatim}
+The first part of the line {\tt GfsOutput \{\}} defines the {\tt
+GfsEvent} part of {\tt GfsOutput} and follows the syntax above. In the
+remainder of this tutorial, I will use the following notation to
+express this inheritance of syntax:
+\begin{verbatim}
+[GfsEvent] filename-%d-%f-%ld
+\end{verbatim}
+to avoid repeating the whole thing for every derived objects.
+
+The second part {\tt filename-\%d-\%f-\%ld} specifies where to output
+things. The {\tt \%d}, {\tt \%f} and {\tt \%ld} characters are
+formatting strings which follow the C language syntax and will be
+replaced every time the event takes place according to:
+\begin{description}
+\item[{\tt \%d}] integer replaced with the current process number (used when
+running the parallel version of Gerris).
+\item[{\tt \%f}] floating-point number replaced with the current
+physical time.
+\item[{\tt \%ld}] (long) integer replaced with the current time step number.
+\end{description}
+Of course, you are free not to specify any of these, in which case the 
+output will just be appended to the same file every time the event
+takes place. There are also two filenames which have a special
+meaning: {\tt stdout} and {\tt stderr}, for the standard output and
+standard error of the shell respectively.
+
+We now add the following to our simulation file:
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 50 }
+  GfsRefine 6
+  GfsInit {} {
+    U = (0.5 - rand()/(double)RAND_MAX)
+    V = (0.5 - rand()/(double)RAND_MAX)
+  }  
+  GfsOutputTime            { istep = 10 } stdout
+  GfsOutputProjectionStats { istep = 10 } stdout
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+The first line we added tells the program to output information about
+the time every 10 time steps on the standard output. The second line
+outputs statistics about the projection part of the algorithm.
+
+You can now run the code like this:
+\begin{verbatim}
+% gerris2D vorticity.gfs
+\end{verbatim}
+and you should get an output in your console looking like this (you
+can stop the program using {\tt Ctrl-C}):
+\begin{verbatim}
+step:       0 t:      0.00000000 dt:  0.000000e+00
+MAC projection        before     after       rate
+    niter:    0
+    residual.bias:    0.000e+00  0.000e+00
+    residual.first:   0.000e+00  0.000e+00   0.0
+    residual.second:  0.000e+00  0.000e+00   0.0
+    residual.infty:   0.000e+00  0.000e+00   0.0
+Approximate projection
+    niter:    0
+    residual.bias:    0.000e+00  0.000e+00
+    residual.first:   1.050e-14  1.050e-14   0.0
+    residual.second:  1.612e-14  1.612e-14   0.0
+    residual.infty:   7.105e-14  7.105e-14   0.0
+step:      10 t:      0.02190704 dt:  2.801016e-03
+MAC projection        before     after       rate
+    niter:    5
+    residual.bias:   -3.053e-16  1.403e-16
+    residual.first:   3.365e+01  2.949e-05  16.3
+    residual.second:  4.274e+01  4.676e-05  15.6
+    residual.infty:   1.954e+02  3.285e-04  14.3
+Approximate projection
+    niter:    5
+    residual.bias:    9.714e-17  2.874e-16
+    residual.first:   3.322e+01  2.548e-05  16.7
+    residual.second:  4.250e+01  4.062e-05  16.0
+    residual.infty:   1.880e+02  3.380e-04  14.1
+step:      20 t:      0.05278371 dt:  3.531551e-03
+MAC projection        before     after       rate
+    niter:    5
+...
+\end{verbatim}
+The lines starting with {\tt step:} are written by {\tt
+GfsOutputTime}. They give the time step number, corresponding physical
+time and the time step used for the previous iteration.
+
+The other lines are written by {\tt GfsOutputProjectionStats} and give
+you an idea of the divergence errors and convergence rate of the two
+projection steps (MAC and approximate) performed during the previous
+iteration. The various norms of the residual of the solution of the
+Poisson equation are given before and after the projection step. The
+{\tt rate} column gives the average amount by which the divergence is
+reduced by each iteration of the multigrid solver.
+
+Well, numbers are great but what about some images? What we want to 
+do, for example, is output some graphical representation of a given
+scalar field. In 2D, a simple way to do that is to create an image
+where each pixel is coloured according to the local value of the
+scalar. Gerris provides an object to do just that: {\tt GfsOutputPPM}
+which will create a {\sc PPM} (Portable PixMap) image. This object is
+derived from a more general class used to deal with scalar fields:
+{\tt GfsOutputScalar} following this syntax:
+\begin{verbatim}
+[GfsOutput] { v = U min = -1 max = 2.5 }
+\end{verbatim}
+where as before the square brackets express inheritance from the
+parent class. The {\tt v} identifier specifies what scalar field we
+are dealing with, one of:
+\begin{description}
+\item[{\tt U}, {\tt V} (and {\tt W} in 3D)]: components of the velocity.
+\item[{\tt P}]: pressure.
+\item[{\tt C}]: passive tracer.
+\item[{\tt Vorticity}]: vorticity (norm of the vorticity vector in 3D).
+\item[{\tt Velocity}]: norm of the velocity.
+\end{description}
+The {\tt min} and {\tt max} values specify the minimum and maximum
+values this scalar can take. If they are not given, they are computed
+every time the event takes place.
+
+We can now use this in our simulation file:
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 50 }
+  GfsRefine 6
+  GfsInit {} {
+    U = (0.5 - rand()/(double)RAND_MAX)
+    V = (0.5 - rand()/(double)RAND_MAX)
+  }  
+  GfsOutputTime            { istep = 10  } stdout
+  GfsOutputProjectionStats { istep = 10  } stdout
+  GfsOutputPPM             { step = 1 } vorticity-%4.1f.ppm { v = Vorticity }
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+The code will output every 1 time units a {\sc PPM} image
+representing the vorticity field. The result will be written in files 
+named: {\tt vorticity-00.0.ppm}, {\tt vorticity-01.0.ppm}\dots (if the 
+{\tt \%4.1f} thing is not familiar, consult a C book or try {\tt \% man 
+3 printf}).
+
+If you re-run the program using this new simulation file, you will get
+a number of {\sc PPM} files (51 to be precise) you can then visualise
+with any image editing or viewing tool. I would recommend the very
+good \htmladdnormallinkfoot{ImageMagick toolbox}{http://www.imagemagick.org}. If you
+run a Linux box, these tools are very likely to be already installed
+on your system. Try typing this in your working directory:
+\begin{verbatim}
+% display *.ppm
+\end{verbatim}
+If it works, you should see a small (64x64) image representing the
+initial vorticity field. If you click on it, a menu will
+appear. Select File$\rightarrow$Next and look at the evolution of the
+vorticity field with time (you can also use the space bar and
+backspace key to change back and forth). You might also want to try
+the {\tt animate *.ppm} command. Read the man pages of ImageMagick if
+you want to know more. Note that you can use these tools also while
+Gerris is running (and creating new images). With a bit of patience
+you will get the image on figure \ref{vorticity} at $t=18$ (resolution
+has been increased to $128\times 128$).
+\begin{figure}
+\begin{center}
+\includegraphics[width=0.4\hsize]{vorticity.eps}
+\end{center}
+\caption{Vorticity field for the initial random vorticity problem at
+$t=18$.}
+\label{vorticity}
+\end{figure}
+
+Before we carry on, we are going to make two modifications to the
+simulation file. First of all, it is not really handy to generate one
+file for every image generated. ImageMagick (and most other programs)
+can deal with multiple {\sc PPM} images contained within the same
+file. Secondly, in the sequence of images we generate, a given value
+of the vorticity does not always correspond to the same colour
+(because the minimum and maximum values of the vorticity can vary in
+time). We can fix that like this:
+\begin{verbatim}
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 50 }
+  GfsRefine 6
+  GfsInit {} {
+    U = (0.5 - rand()/(double)RAND_MAX)
+    V = (0.5 - rand()/(double)RAND_MAX)
+  }  
+  GfsOutputTime            { istep = 10   } stdout
+  GfsOutputProjectionStats { istep = 10   } stdout
+  GfsOutputScalarStats     { istep = 10   } stdout { v = Vorticity }
+  GfsOutputPPM             { step = 0.1 } vorticity.ppm {
+    v = Vorticity 
+    min = -10
+    max =  10
+  }
+}
+GfsBox {}
+1 1 right
+1 1 top
+\end{verbatim}
+We have now specified fixed bounds for the vorticity (using the {\tt
+min} and {\tt max} identifiers). Each {\sc PPM} image will be appended to
+the same file: {\tt vorticity.ppm}.
+
+How did I choose the minimum and maximum values for the vorticity? The 
+line {\tt GfsOutputScalarStats \{ istep = 10 \} stdout \{ v = Vorticity
+\}}, writes the minimum, average, standard deviation and maximum
+values of the vorticity. By re-running the simulation and looking at
+these values it is easy to find a suitable range.
+
+\section{A more complex example with solid boundaries}
+
+In this section we will see how to set up a simulation for the flow past 
+a solid body (a half-cylinder) in a narrow channel. While doing that
+we will also encounter new ways of displaying simulation results.
+
+\subsection{Domain geometry and boundary conditions}
+
+What we want is a narrow channel ($4\times 1$ for example). From the
+previous example, we know that we can build it like this:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 0 }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 2 right
+2 3 right
+3 4 right
+\end{verbatim}
+i.e. four boxes, box 1 connected to box 2 horizontally (to the right),
+box 2 connected to box 3 horizontally and box 3 connected to box 4
+horizontally. Box 1 is centered on the origin and is of size one. All
+the other boxes are positioned accordingly. We now have our $4\times
+1$ rectangular domain.
+
+\subsubsection{Boundary conditions}
+
+What about boundary conditions? By default Gerris assumes that
+boundaries are solid walls with slip conditions for the velocity
+(i.e. the tangential stress on the wall is zero). For the moment we
+then have defined a rectangular box closed on all sides by solid
+walls.
+
+What we really want is to specify an input velocity on the left side
+of the box and some sort of output condition on the right side. We can
+do that like this:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 0 }
+}
+GfsBox { left = GfsBoundaryInflowConstant 1 }
+GfsBox {}
+GfsBox {}
+GfsBox { right = GfsBoundaryOutflow }
+1 2 right
+2 3 right
+3 4 right
+\end{verbatim}
+The whole left side of the first (leftmost) box is now defined to be a {\tt
+GfsBoundaryInflowConstant} object and the whole right side of the last
+(rightmost) box a {\tt GfsBoundaryOutflow} object. Again, boundary
+conditions objects are all derived from the {\tt GfsBoundary} object
+and, as initial conditions, new objects can be easily written by the
+user (see also section \ref{morebc}).
+
+We see that {\tt GfsBoundaryInflowConstant} takes one argument which is
+the value of the (constant) normal velocity applied to this
+boundary. All the other variables (pressure, tracer concentration
+etc...) follow a zero gradient condition.
+
+{\tt GfsBoundaryOutflow} implements a simple outflow boundary condition 
+where the pressure is set to zero as well as the gradient of all other quantities.
+
+\subsubsection{Solid boundaries}
+
+We now have an empty ``wind tunnel'' with a constant inlet velocity of
+norm unity. Gerris can deal with arbitrarily complex solid boundaries
+embedded in the quad/octree mesh. The geometry of the solid boundaries
+is described using {\sc GTS} triangulated surfaces. In 2D, using 3D
+triangulated surfaces seems overkill, as 2D curves would be
+enough. However, Gerris being both a 2D and 3D code it deals with 2D
+solid boundaries exactly as with 3D ones, even if the simulation is
+done only on a 2D cross-section.
+
+Creating 3D polygonal surfaces is not an easy job and is clearly
+outside the scope of this tutorial. There are a number of utilities
+you can use to do that, including big commercial {\sc CAD}
+packages. In general, once you have created a polygonal surface with
+one of these tools it should be relatively easy to convert it to the
+file format used by {\sc GTS}. In particular, most {\sc CAD} packages
+can export to the {\sc STL} (stereolithography) format which is easily
+converted to the {\sc GTS} file format using the {\tt stl2gts} utility
+which comes with the library.
+
+This tutorial comes (handily) with one such file:
+\htmladdnormallinkfoot{{\tt half-cylinder.gts}}
+{\gfsweb/half-cylinder.gts}. You can
+visualise the surface it describes using a program
+called
+\htmladdnormallinkfoot{Geomview}{http://www.geomview.org}. To do this,
+you first need to convert the {\sc GTS} file to a format Geomview
+understands. This can be done using the {\tt gts2oogl} utility like
+this:
+\begin{verbatim}
+% gts2oogl < half-cylinder.gts > half-cylinder.oogl
+\end{verbatim}
+({\sc OOGL} is the file format used by Geomview). {\tt gts2oogl} has a
+number of options. You can have a short explanation of what they do by 
+typing:
+\begin{verbatim}
+% gts2oogl -h
+\end{verbatim}
+If you now start geomview like this:
+\begin{verbatim}
+% geomview half-cylinder.oogl
+\end{verbatim}
+and play around with the pan/rotate/zoom functions of Geomview (read the
+manual for details), you should see something like the image on figure 
+\ref{half-cylinder}.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[width=0.3\hsize]{half-cylinder.eps}
+\end{center}
+\caption{Geomview representation of {\tt half-cylinder.gts}}
+\label{half-cylinder}
+\end{figure}
+You can notice that this is a proper 3D object, even if we are only
+going to simulate the flow in a 2D cross-section. It is also important 
+that the object is ``tall'' enough so that it spans the entire
+``height'' of the 2D domain, as if we were going to simulate the flow
+around it in a proper 3D channel with a square cross-section. The
+orientation of the surface is also important to define what is inside
+(the solid) and what is outside (the fluid).
+
+We can now insert this object in the simulation domain like this:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 0 }
+  GfsSolid half-cylinder.gts
+}
+GfsBox { left = GfsBoundaryInflowConstant 1 }
+GfsBox {}
+GfsBox {}
+GfsBox { right = GfsBoundaryOutflow }
+1 2 right
+2 3 right
+3 4 right
+\end{verbatim}
+add what mesh refinement we want and a few things to output:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 9 }
+  GfsRefine 6
+  GfsSolid half-cylinder.gts
+  GfsInit {} { U = 1 }
+  GfsOutputBoundaries {} boundaries
+  GfsOutputTime { step = 0.02 } stdout
+  GfsOutputProjectionStats { step = 0.02 } stdout
+  GfsOutputPPM { step = 0.02 } vorticity.ppm { 
+    min = -100 max = 100 v = Vorticity 
+  }
+  GfsOutputTiming { start = end } stdout
+}
+GfsBox { left = GfsBoundaryInflowConstant 1 }
+GfsBox {}
+GfsBox {}
+GfsBox { right = GfsBoundaryOutflow }
+1 2 right
+2 3 right
+3 4 right
+\end{verbatim}
+I have added a new {\tt GfsOutput} object we haven't seen yet: {\tt
+GfsOutputTiming}. This object writes a summary of the time taken by
+various parts of the solver. You might also have noticed the unusual
+{\tt start = end} bit ; this just specifies that this event will only
+happen once at the end of the simulation.
+
+Another new output object is {\tt GfsOutputBoundaries}. This object
+writes a geometrical summary (in {\sc OOGL}/Geomview format) of the mesh
+used, including boundary conditions, solid boundaries and so on.
+
+We also initialise the velocity field on the whole domain
+to a constant value (1,0,0). We could have left the
+velocity field to its default value of (0,0,0) but, given that we
+impose inflow boundary conditions, it would have meant that the
+initial velocity would have been strongly divergent. Gerris always
+starts a simulation by a projection step (to fix problems like this)
+but it is always a good idea to start with the best possible velocity
+field.
+
+We can now run the code:
+\begin{verbatim}
+% gerris2D half-cylinder.gfs
+\end{verbatim}
+It is going to take a while to complete, but remember that you can
+look at files while they are being generated. The first file which
+will be generated is {\tt boundaries}. If you load it in Geomview, you
+should get something like figure \ref{boundaries} (you probably want
+to disable automatic normalization in Geomview by selecting
+Inspect$\rightarrow$Appearance$\rightarrow$Normalize$\rightarrow$None).
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[angle=90,width=0.8\hsize]{boundaries.eps}
+\end{center}
+\caption{Representation of boundary conditions and solid boundaries}
+\label{boundaries}
+\end{figure}
+The black lines represent the boundaries between solid cells and fluid 
+cells. If you zoom in on the half-cylinder, you will see that it is
+represented by lines following the grid (it is ``lego-looking''). This 
+does not mean that the ``real'' (i.e. computational) solid boundary is 
+also lego-looking because fluid cells can be cut by the solid
+boundaries, in which case the algorithm properly takes into account
+the corresponding cell geometry.
+
+Each {\tt GfsBoundary} object is colour-coded. From the colours in the
+picture we see that we have indeed an inflow boundary condition on the
+left side (blue) and an outflow boundary condition on the right side
+(green).
+
+You can also load in the full half-cylinder geometry we created
+before: {\tt half-cylinder.oogl} or visualise the {\sc PPM} files using {\tt 
+animate} and {\tt display} as in the previous example. By the way, a
+useful feature of {\tt display} is that you can zoom in by clicking on
+the middle button in the image being displayed.
+
+\subsection{Saving the whole simulation}
+
+Hmm, this simulation is taking quite a while\dots What if we want to
+stop the simulation, make some modifications to the simulation file
+and restart where we left from? Or equivalently, save the whole
+simulation at regular intervals for latter post-processing?
+
+You can do this using the {\tt GfsOutputSimulation} object. Like this
+for example:
+\begin{verbatim}
+GfsOutputSimulation { step = 0.1 } half-cylinder-%3.1f.gfs {
+  variables = U,V,P
+}
+\end{verbatim}
+where {\tt variables} defines which variables you want to save. By
+default all the variables are saved.
+
+If you now re-run the simulation, you will get a new file every 0.1
+time units. This file is a valid simulation file (like {\tt
+half-cylinder.gfs}) and you can use it directly to restart the
+simulation from this point onward. If you edit it, you will see that
+the general structure is the same as usual but for five pretty big
+chunks of data. 
+
+The first chunk starts with {\tt GfsSolid} and is
+just the data contained in {\tt half-cylinder.gts} but this time
+embedded directly into the simulation file. The goal there is to have
+fully self-contained simulations files which you can just move around
+without having to keep track of twenty different files.
+
+The four other chunks are each associated with a {\tt GfsBox} and
+contain both the topology of the corresponding cell tree but also the
+associated physical data, solid boundary definitions etc...
+
+You can of course edit this file, add new outputs and so on and
+restart the simulation from where you left it.
+
+\subsection{Visualisation}
+
+\subsubsection{\label{gfsview}GfsView}
+
+GfsView is a tool written specifically to visualise Gerris simulation
+files. It is still young but fully usable both for 2D and 3D
+simulations. Its main advantage over other options and the reason for
+its existence is that it makes full use of the adaptive nature of the
+octree representation at the visualisation level. The octree structure
+is used within GfsView to dynamically select the appropriate level of
+refinement depending on the viewpoint, zoom and rendering speed. It is
+also used to efficiently compute complex geometrical entities such as
+isosurfaces or cut-planes.
+
+The more classical viewers such as openDX or MayaVi are designed for
+either regular Cartesian grids or fully-unstructured meshes and do not
+take advantage of the octree representation (worse still, the octree
+representation first needs to be converted to Cartesian or
+fully-unstructured meshes before being imported into these programs).
+
+To install GfsView, you need to have the
+\htmladdnormallinkfoot{Gtk+}{http://www.gtk.org} toolkit installed on
+your system. If you are running a Linux machine, Gtk+ is most probably
+already installed. You will also need the
+\htmladdnormallinkfoot{GtkGlExt}{http://gtkglext.sourceforge.net/}
+OpenGL extension to Gtk+.
+
+If you are running a Debian-based system, you can install these packages using
+\begin{verbatim}
+% apt-get install libgtkglext1-dev
+\end{verbatim}
+
+If you then download a recent version of GfsView from the Gerris web
+site (either an official release or a snapshot) and do the now classical:
+\begin{verbatim}
+% gunzip gfsview.tar.gz
+% tar xvf gfsview.tar
+% cd gfsview
+% ./configure --prefix=/home/joe/local
+% make
+% make install
+\end{verbatim}
+you will be able to start GfsView using:
+\begin{verbatim}
+% gfsview2D half-cylinder-0.5.gfs
+\end{verbatim}
+Note that you can also install the most recent GfsView version using
+darcs and {\tt http://gfs.sourceforge.net/darcs/gfsview/gfsview-mainline} as source
+repository (you will also need to install Gerris this way, see section
+\ref{build_darcs} for details).
+
+Clicking on ``Linear'', ``Vectors'' and ``Solid'' in the toolbar and
+changing the vector length by editing the properties of the
+``Vectors'' object (select the object then choose
+``Edit$\rightarrow$Properties'') you should be able to get something
+looking like figure \ref{fig:gfsview}. You can pan by dragging the right
+mouse button, zoom by dragging the middle button and rotate by
+dragging the left button.
+\begin{figure}[htbp]
+\begin{center}
+%% \htmlimage{scale=2.0,external,thumbnail=1}
+\includegraphics[width=\hsize]{gfsview.eps}
+\end{center}
+\caption{Screenshot of a GfsView session.}
+\label{fig:gfsview}
+\end{figure}
+
+While by no means complete, you can already do many things with
+GfsView. I hope it is fairly user-friendly so just play with it and
+discover for yourself.
+
+\subsubsection{Some post-processing using {\tt gfs2oogl}}
+
+Gerris comes with a utility called {\tt gfs2oogl} which converts
+simulation files to various representations in {\sc OOGL} format. We are
+just going to look at two types of representations {\tt gfs2oogl} can
+do: scalar field cross-sections and vector fields.
+
+First of all, you can access a small summary of the options of {\tt
+gfs2oogl} by typing:
+\begin{verbatim}
+% gfs2oogl2D -h
+\end{verbatim}
+By default {\tt gfs2oogl} will generate the same output as {\tt
+GfsOutputBoundaries} like this:
+\begin{verbatim}
+% gfs2oogl2D < half-cylinder-0.1.gfs > boundaries.oogl
+\end{verbatim}
+To generate an {\sc OOGL} representation of a scalar field (a coloured square
+for each discretisation cell) do this:
+\begin{verbatim}
+% gfs2oogl2D -S -z 0 -c Vorticity < half-cylinder-0.5.gfs > squares.oogl
+\end{verbatim}
+which tells {\tt gfs2oogl} to do a cross-section for $z = 0$ ({\tt -z
+0}) represented by squares ({\tt -S}) and colored according to the local
+vorticity ({\tt -c Vorticity}).
+To generate a vector field representing the velocity try:
+\begin{verbatim}
+% gfs2oogl2D -V 2 -z 0 < half-cylinder-0.5.gfs > vectors.oogl
+\end{verbatim}
+where {\tt -V 2} specifies that the maximum length of the vector is
+twice the dimension of the smallest cell in the domain.
+
+If you now load all these files in Geomview and do a bit of panning
+and zooming around (and possibly tune things like face shading) you
+should get an image looking like figure \ref{gfs2oogl}.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[angle=90,width=0.6\hsize]{gfs2oogl.eps}
+\end{center}
+\caption{Scalar and vector representation generated using {\tt
+gfs2oogl}.}
+\label{gfs2oogl}
+\end{figure}
+
+\subsection{Using dynamic adaptive mesh refinement}
+
+For the moment our simulation is not very well resolved. We could always 
+change the {\tt GfsRefine 6} line to something bigger but it would not
+make really good use of the quadtree approach used in Gerris. A code
+using a simple regular Cartesian grid approach would be faster and
+would produce the same results. Instead we are going to use {\em
+dynamic adaptive mesh refinement}, where the quadtree structure of the 
+discretisation is used to adaptively follow the small structures of
+the flow, thus concentrating the computational effort on the area
+where it is most needed. 
+
+This is done using yet another object class: {\tt GfsAdapt}, also derived 
+from {\tt GfsEvent}. Various criteria can be used to determine where
+refinement is needed. In practice, each criterium will be defined
+through a different object derived from {\tt GfsAdapt}. If several {\tt 
+GfsAdapt} objects are specified in the same simulation file, refinement 
+will occur whenever at least one of the criteria is verified.
+
+For this first example, we will use a simple criterium based on the
+local value of the vorticity. A cell will be refined whenever
+$$
+{|\nabla\times{\bf v}|\Delta x\over\max|{\bf v}|} > \delta,
+$$
+where $\Delta x$ is the size of the cell and $\delta$ is a
+user-defined threshold which can be interpreted as the maximum angular 
+deviation (caused by the local vorticity) of a particle traveling at 
+speed $\max|{\bf v}|$ across the cell. This criterium is implemented
+by the {\tt GfsAdaptVorticity} object.
+
+The general syntax for an {\tt GfsAdapt} object is:
+\begin{verbatim}
+[GfsEvent] { mincells = 1 maxcells = 100000 minlevel = 1 maxlevel = 10 cmax = 1e-2 }
+\end{verbatim}
+where {\tt mincells} specifies the minimum number of cells in the
+domain, {\tt maxcells} the maximum number of cells, {\tt minlevel} the
+level below which it is not possible to coarsen a cell, {\tt maxlevel}
+the level above which it is not possible to refine a cell and {\tt
+  cmax} the maximum cell cost. The default values are 0 for {\tt
+  minlevel} and {\tt mincells} and infinite for {\tt maxlevel} and
+{\tt maxcells}. An important point is that, for the moment, it is not
+possible to dynamically refine solid boundaries. A simple solution to
+this restriction is to always refine the solid boundary with the
+maximum resolution at the start of the simulation and to restrict the
+refinement using the {\tt maxlevel} identifier in {\tt GfsAdapt}.
+
+What happens if the maximum number of cells is reached? The refinement algorithm will keep the number of cells fixed but will minimize the maximum cost over all the cells. This can be used for example to run a constant-size simulation where the cells are optimally distributed across the simulation domain. This would be done by setting {\tt maxcells} to the desired number and {\tt cmax} to zero.
+
+Following this we can modify our simulation file:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 9 }
+  GfsRefine 7
+  GfsSolid half-cylinder.gts
+  GfsInit {} { U = 1 }
+#  GfsOutputBoundaries {} boundaries
+  GfsAdaptVorticity { istep = 1 } { maxlevel = 7 cmax = 1e-2 }
+  GfsOutputTime { step = 0.02 } stdout
+  GfsOutputBalance { step = 0.02 } stdout
+  GfsOutputProjectionStats { step = 0.02 } stdout
+  GfsOutputPPM { step = 0.02 } vorticity.ppm {
+    min = -100 max = 100 v = Vorticity
+  }
+  GfsOutputSimulation { step = 0.1 } half-cylinder-%3.1f.gfs {
+    variables = U,V,P
+  }
+  GfsOutputTiming { start = end } stdout
+}
+GfsBox { left = GfsBoundaryInflowConstant 1 }
+GfsBox {}
+GfsBox {}
+GfsBox { right = GfsBoundaryOutflow }
+1 2 right
+2 3 right
+3 4 right
+\end{verbatim}
+We have added two lines and commented out (using {\tt \#}) the line
+outputting the boundaries (we don't need that anymore, we have the
+simulation files).
+
+The first line we added says that we want to refine dynamically the
+mesh through the {\tt GfsAdaptVorticity} object applied every timestep
+({\tt istep = 1}). The $\delta$ parameter ({\tt cmax}) is set to $10^{-2}$.
+
+The second line we added is a new {\tt GfsOutput} object which displays 
+the ``balance'' of the domain sizes across the different processes
+(when Gerris is ran in parallel). We will use this to monitor how the
+number of cells evolves with time as the simulation refines or
+coarsens the mesh according to our vorticity criterium.
+
+We can now run this new simulation. If the previous simulation did not
+complete yet, don't be afraid to abort it ({\tt Ctrl-C}), this one is going to
+be better (and faster).
+\begin{verbatim}
+% gerris2D half-cylinder.gfs
+\end{verbatim}
+If we now look at the balance summary written by {\tt
+GfsOutputBalance}, we see that initially ({\tt step: 0}) the total
+number of cells (on all levels) is 86966, which corresponds to a
+constant resolution of $4\times 2^7\times 2^7=512\times 128$. At step
+10 the number of cells is down to 990 with a corresponding increase in 
+computational speed. If we now look at the first simulation file we
+saved, using:
+\begin{verbatim}
+% gfs2oogl2D < half-cylinder-0.1.gfs > boundaries
+% gfs2oogl2D -S -z 0 -c Vorticity < half-cylinder-0.1.gfs > squares.oogl
+\end{verbatim}
+we obtain figure \ref{refined1} showing not only the domain boundaries 
+as usual, but also the boundaries (thin black lines) between different
+levels of refinement.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[angle=90,width=0.6\hsize]{refined1.eps}
+\end{center}
+\caption{Dynamic adaptive mesh refinement $t=0.1$}
+\label{refined1}
+\end{figure}
+We see that the mesh is very refined around the solid and around the
+two vortices developing at the trailing edge and very coarse (one cell
+per box only) on the downstream part of the domain. If you are not
+sure what these thin black lines represent, just switch on the edge
+representation in Geomview (using the Inspect$\rightarrow$Appearance menu). You
+will get a picture looking like figure \ref{refined1-cells}, showing
+all the cells used for the discretisation.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[angle=90,width=0.6\hsize]{refined1_cells.eps}
+\end{center}
+\caption{Dynamic adaptive mesh refinement $t=0.1$. Detail of the cells.}
+\label{refined1-cells}
+\end{figure}
+As the simulation goes on, you can see the number of cells in the
+domain increase as the trailing vortices develop. With a bit of
+patience you will get to figure \ref{refined2} showing the fully
+developed Von Karman vortex street with patches of increased
+resolution following each vortex. Even when the flow is fully
+developed using adaptive mesh refinement still saves a factor of \~{}6 in
+time and memory use. The advantage of adaptive mesh refinement is even
+more obvious in situations where it is necessary to use very large
+domains to avoid any contamination of the solution by the boundary
+conditions.
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[angle=90,width=0.8\hsize]{refined2.eps}
+\end{center}
+\caption{Dynamic adaptive mesh refinement $t=9$.}
+\label{refined2}
+\end{figure}
+You should also try to {\tt animate vorticity.ppm} which by now should 
+give you a nice animation of the developing trailing vortices becoming 
+unstable and generating the Von Karman street. If ImageMagick is
+properly installed on your system you can also try:
+\begin{verbatim}
+% convert vorticity.ppm vorticity.mpg
+\end{verbatim}
+which will produce a much smaller {\sc MPEG} video file, suitable for
+distribution through the network.
+
+\section{Going further}
+
+\subsection{More on boundary conditions}
+\label{morebc}
+
+Up to now we have only dealt with ``pre-packaged'' boundary conditions
+such as {\tt GfsBoundaryInflowConstant} and {\tt GfsBoundaryOutflow}.
+What if you need more specific boundary conditions?
+
+For most practical problems, boundary conditions can be reduced to two
+main categories: Dirichlet boundary conditions for which the value of
+the variable is set and Neumann boundary conditions for which the
+value of the derivative of the variable is set. As we have seen
+earlier, the default boundary condition in Gerris is Dirichlet (zero)
+for the normal components of the velocity and Neumann (zero) for all
+other variables.
+
+Let us say that we want to impose a Poiseuille (parabolic) profile
+rather than a constant inflow velocity for the half-cylinder problem
+i.e. we want a Dirichlet boundary condition on the normal component of
+the velocity ({\tt U}) with an imposed parabolic profile. This can
+easily be done in Gerris like this:
+\begin{verbatim}
+...
+GfsBox { left = GfsBoundary {
+                  GfsBcDirichlet U { return 1. - 4.*y*y; }
+                  GfsBcDirichlet V 0
+                }
+       }
+GfsBox {}
+GfsBox {}
+GfsBox { right = GfsBoundaryOutflow }
+...
+\end{verbatim}
+Similarly a Neumann boundary condition on variable {\tt X} would use
+{\tt GfsBcNeumann X ...}
+
+\subsection{Adding tracers}
+
+In the half cylinder example, it would be nice to be able to visualise
+the flow using for example a passive tracer injected at the inlet.
+This is very simple, just modify the {\tt half-cylinder.gfs} parameter
+file like this:
+\begin{verbatim}
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+  GfsTime { end = 9 }
+  GfsRefine 7
+  GfsSolid half-cylinder.gts
+  GfsVariableTracer {} T
+  ...
+  GfsOutputPPM { step = 0.02 } tracer.ppm {
+    min = 0 max = 1 v = T
+  }
+  GfsOutputSimulation { step = 0.1 } half-cylinder-%3.1f.gfs {
+    variables = U,V,P,T
+  }
+  ...
+}
+GfsBox { left = GfsBoundary {
+                  GfsBcDirichlet U 1
+                  GfsBcDirichlet V 0
+                  GfsBcDirichlet T { return y > 0. ? 1. : 0.; }
+                } 
+       }
+...
+\end{verbatim}
+which will inject tracer {\tt T} at the inlet only in the upper half
+of the channel.
+
+The adaptive refinement algorithm shoud also take your tracer into account. Try this
+\begin{verbatim}
+  ...
+  GfsAdaptVorticity { istep = 1 } { maxlevel = 7 cmax = 1e-2 }
+  GfsAdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T
+  ...
+\end{verbatim}
+which will adapt using both the gradient of tracer {\tt T} and the vorticity.
+
+You can have any number of tracers you want, they are dynamically
+allocated.
+
+\subsection{Adding diffusion terms}
+
+Up to now, we have only considered inviscid, incompressible flows.
+Without going into the details, this type of problems require the
+solution of two main subproblems: solving a Poisson equation for the
+pressure and an advection equation for the momentum and tracers with
+the corresponding boundary conditions.
+
+Gerris can also solve a third class of subproblems: diffusion
+equations. Diffusion equations are similar to Poisson equations (they
+both involve Laplacian operators) and can be solved efficiently using
+the same multigrid solver we use for the pressure.
+
+In practice adding diffusion to a given tracer is as simple as adding:
+\begin{verbatim}
+  ...
+  GfsSourceDiffusion {} T 0.01
+  ...
+\end{verbatim}
+to the parameter file, where 0.01 is the value of the diffusion
+coefficient.
+
+\subsubsection{\label{diffusionbc}Boundary conditions for diffusion terms}
+
+What if we want to modify the tracer example above so that now the
+half-cylinder itself is a (diffusive) source of tracer rather than the
+inlet? We need to be able to impose this boundary condition on the
+embedded solid surface. On embedded solids, the default boundary
+conditions for the diffusion equation is Neumann (zero flux) for
+tracers and Dirichlet (no-slip) for the velocity components. To change
+that use
+\begin{verbatim}
+  ...
+  GfsVariableTracer T
+  GfsSourceDiffusion {} T 0.001
+  GfsSurfaceBc T Dirichlet 1
+  ...
+\end{verbatim}
+and change the inlet boundary condition back to
+\begin{verbatim}
+  ...
+  GfsBox { left = GfsBoundary {
+                  GfsBcDirichlet U 1
+                  GfsBcDirichlet V 0
+                } 
+       }
+  ...
+\end{verbatim}
+
+\subsection{Outputs}
+
+\subsection{Boundary conditions}
+
+\section{Running Gerris in parallel}
+
+\section{Learning more}
+
+While this tutorial should give you a good overview of Gerris, it is
+by no means a complete description. To learn more you should first
+consult the \htmladdnormallinkfoot{Gerris Frequently Asked Questions}{\gfsweb/wiki/index.php/FAQ} and the
+\htmladdnormallinkfoot{Gerris object hierarchy}{\gfsweb/wiki/index.php/Object\_hierarchy} which describes each
+object and the corresponding file parameters in more detail.
+
+You should also have a look at the \htmladdnormallinkfoot{Gerris
+  Examples}{\gfsweb/examples/examples} page for examples of how to
+use Gerris for a range of problems. The parameter files are
+cross-linked with the reference manual.
+
+Another source of more advanced examples is the \htmladdnormallinkfoot{Gerris test suite}{\gfsweb/tests/tests/index.html}.
+
+If things are still unclear you can ask for help on the
+\htmladdnormallinkfoot{{\tt gfs-users} mailing
+  list}{\gfsweb/mailinglists.html}. Please note that you
+first need to subscribe to the list to be able to post messages.
+
+\section{Do you want to help?}
+
+The idea behind Gerris and other free software projects is that
+transparency, free exchange of information and cooperation benefit
+individuals but also society as a whole. If you are a scientist, you
+know that these same principles are also keys to the efficiency of
+Science.
+
+Helping with Gerris development can be done in various ways and aside
+from giving you this altruistic, warm fuzzy feeling of helping others
+will also benefit you directly. A few concrete simple ways of helping
+are (in approximate order of difficulty):
+\begin{itemize}
+\item Use the code, comment on the problems you find, what you like, don't like about it.
+\item Share your results with other Gerris users, write a web page
+  about the problem you solved using Gerris etc\dots
+\item If you publish papers using Gerris, send me the reference. It is
+  very useful to be able to show evidence of wider usage when seeking
+  continued funding for the project.
+\item Also, if Gerris capabilities are central to your article feel
+  free to ask me to be a co-author on your paper\dots
+\item Have a look at the Gerris internals (write your own modules) and share them with us.
+\item Think of ways to extend Gerris for your own problems, implement
+  them and share them with us (you can count on my and other
+  developers' help).
+\end{itemize}
+
+\end{document}
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..e4160c9
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,325 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2004-04-01.17
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=
+transform_arg=
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+
+usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 -d DIRECTORIES...
+
+In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
+In the second, create the directory path DIR.
+
+Options:
+-b=TRANSFORMBASENAME
+-c         copy source (using $cpprog) instead of moving (using $mvprog).
+-d         create directories instead of installing files.
+-g GROUP   $chgrp installed files to GROUP.
+-m MODE    $chmod installed files to MODE.
+-o USER    $chown installed files to USER.
+-s         strip installed files (using $stripprog).
+-t=TRANSFORM
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+        shift
+        continue;;
+
+    -c) instcmd=$cpprog
+        shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit 0;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+        shift
+        continue;;
+
+    --version) echo "$0 $scriptversion"; exit 0;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+	test -n "$dir_arg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      instcmd=:
+      chmodcmd=
+    else
+      instcmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp" || lasterr=$?
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $instcmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    # If we're going to rename the final executable, determine the name now.
+    if test -z "$transformarg"; then
+      dstfile=`basename "$dst"`
+    else
+      dstfile=`basename "$dst" $transformbasename \
+               | sed $transformarg`$transformbasename
+    fi
+
+    # don't allow the sed command to completely eliminate the filename.
+    test -z "$dstfile" && dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Move or copy the file name to the temp name
+    $doit $instcmd "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $instcmd $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 0000000..e420fac
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,6964 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008  Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="1.5.26 Debian 1.5.26-1ubuntu1"
+TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
+
+# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+lt_env=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+	  save_$lt_var=\$$lt_var
+	  lt_env=\"$lt_var=\$$lt_var \$lt_env\"
+	  $lt_var=C
+	  export $lt_var
+	fi"
+done
+
+if test -n "$lt_env"; then
+  lt_env="env $lt_env"
+fi
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+duplicate_deps=no
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+	# Failing that, at least try and use $RANDOM to avoid a race
+	my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+	save_mktempdir_umask=`umask`
+	umask 0077
+	$mkdir "$my_tmpdir"
+	umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+	exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+	$SED -n -e '1,100{
+		/ I /{
+			s,.*,import,
+			p
+			q
+			}
+		}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	case $arg in
+	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	    # Double-quote args containing other shell metacharacters.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    CC_quoted="$CC_quoted $arg"
+	  done
+	    case "$@ " in
+	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  $echo "$modename: unable to infer tagged configuration"
+	  $echo "$modename: specify a tag with \`--tag'" 1>&2
+	  exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+
+    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+      exit $EXIT_FAILURE
+    fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+    my_status=""
+
+    $show "${rm}r $my_gentop"
+    $run ${rm}r "$my_gentop"
+    $show "$mkdir $my_gentop"
+    $run $mkdir "$my_gentop"
+    my_status=$?
+    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+      exit $my_status
+    fi
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  extracted_serial=`expr $extracted_serial + 1`
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      $show "${rm}r $my_xdir"
+      $run ${rm}r "$my_xdir"
+      $show "$mkdir $my_xdir"
+      $run $mkdir "$my_xdir"
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+	exit $exit_status
+      fi
+      case $host in
+      *-darwin*)
+	$show "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	if test -z "$run"; then
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+	  if test -n "$darwin_arches"; then 
+	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+	      lipo -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    ${rm}r unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd "$darwin_orig_dir"
+ 	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	fi # $run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+        ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+    func_extract_archives_result="$my_oldobjs"
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+	$echo "$progname: invalid tag name: $tagname" 1>&2
+	exit $EXIT_FAILURE
+	;;
+      esac
+
+      case $tagname in
+      CC)
+	# Don't test for the "default" C tag, as we know, it's there, but
+	# not specially marked.
+	;;
+      *)
+	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+	  taglist="$taglist $tagname"
+	  # Evaluate the configuration.
+	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+	else
+	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
+	fi
+	;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "\
+$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
+
+Copyright (C) 2008  Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $?
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $?
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $?
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+	case $arg in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  if test -n "$libobj" ; then
+	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-static | -prefer-pic | -prefer-non-pic)
+	  later="$later $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+ 	  for arg in $args; do
+	    IFS="$save_ifs"
+
+	    # Double-quote args containing other shell metacharacters.
+	    # Many Bourne shells cannot handle close brackets correctly
+	    # in scan sets, so we specify it separately.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    lastarg="$lastarg $arg"
+	  done
+	  IFS="$save_ifs"
+	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	* )
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, and some SunOS ksh mistreat backslash-escaping
+      # in scan sets (worked around with variable expansion),
+      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
+      # at all, so we specify them separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.[fF][09]?) xform=[fF][09]. ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    *.obj) xform=obj ;;
+    *.sx) xform=sx ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+    case $qlibobj in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qlibobj="\"$qlibobj\"" ;;
+    esac
+    test "X$libobj" != "X$qlibobj" \
+	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
+	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+      $echo "$srcfile" > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+    case $qsrcfile in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+      qsrcfile="\"$qsrcfile\"" ;;
+    esac
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+	$show "$mkdir ${xdir}$objdir"
+	$run $mkdir ${xdir}$objdir
+	exit_status=$?
+	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+	  exit $exit_status
+	fi
+      fi
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval $lt_env "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	$show "$mv $output_obj $lobj"
+	if $run $mv $output_obj $lobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval $lt_env "$command"; then :
+      else
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    single_module="${wl}-single_module"
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+	;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat $save_arg`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		# If there is no directory component, then add one.
+		case $arg in
+		*/* | *\\*) . $arg ;;
+		*) . ./$arg ;;
+		esac
+
+		if test -z "$pic_object" || \
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none && \
+		   test "$non_pic_object" = none; then
+		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+		  exit $EXIT_FAILURE
+		fi
+
+		# Extract subdirectory from the argument.
+		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		if test "X$xdir" = "X$arg"; then
+		  xdir=
+		else
+		  xdir="$xdir/"
+		fi
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  libobjs="$libobjs $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if test -z "$run"; then
+		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+		  exit $EXIT_FAILURE
+		else
+		  # Dry-run case.
+
+		  # Extract subdirectory from the argument.
+		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		  if test "X$xdir" = "X$arg"; then
+		    xdir=
+		  else
+		    xdir="$xdir/"
+		  fi
+
+		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+		  libobjs="$libobjs $pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      fi
+	    done
+	  else
+	    $echo "$modename: link input file \`$save_arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  compile_command="$compile_command $wl$qarg"
+	  finalize_command="$finalize_command $wl$qarg"
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	shrext)
+  	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	darwin_framework|darwin_framework_skip)
+	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  prev=
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: more than one -exported-symbols argument is not allowed"
+	  exit $EXIT_FAILURE
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework|-arch|-isysroot)
+	case " $CC " in
+	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
+		prev=darwin_framework_skip ;;
+	  *) compiler_flags="$compiler_flags $arg"
+	     prev=darwin_framework ;;
+	esac
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    absdir="$dir"
+	    notinst_path="$notinst_path $dir"
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs -framework System"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      -model)
+	compile_command="$compile_command $arg"
+	compiler_flags="$compiler_flags $arg"
+	finalize_command="$finalize_command $arg"
+	prev=xcompiler
+	continue
+	;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	compiler_flags="$compiler_flags $arg"
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m* pass through architecture-specific compiler args for GCC
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+      # -F/path gives path to uninstalled frameworks, gcc on darwin
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Wl,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $wl$flag"
+	  linker_flags="$linker_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  # If there is no directory component, then add one.
+	  case $arg in
+	  */* | *\\*) . $arg ;;
+	  *) . ./$arg ;;
+	  esac
+
+	  if test -z "$pic_object" || \
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none && \
+	     test "$non_pic_object" = none; then
+	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$xdir" = "X$arg"; then
+	    xdir=
+ 	  else
+	    xdir="$xdir/"
+	  fi
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    libobjs="$libobjs $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if test -z "$run"; then
+	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+	    exit $EXIT_FAILURE
+	  else
+	    # Dry-run case.
+
+	    # Extract subdirectory from the argument.
+	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	    if test "X$xdir" = "X$arg"; then
+	      xdir=
+	    else
+	      xdir="$xdir/"
+	    fi
+
+	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+	    libobjs="$libobjs $pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+	exit $exit_status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    case $linkmode in
+    lib)
+	passes="conv link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    compiler_flags="$compiler_flags $deplib"
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+	    continue
+	  fi
+	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		  library_names=
+		  old_library=
+		  case $lib in
+		  */* | *\\*) . $lib ;;
+		  *) . ./$lib ;;
+		  esac
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+		    test "X$ladir" = "X$lib" && ladir="."
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+	        ;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  *)
+	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    valid_a_lib=no
+	    case $deplibs_check_method in
+	      match_pattern*)
+		set dummy $deplibs_check_method
+	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+		if eval $echo \"$deplib\" 2>/dev/null \
+		    | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		  valid_a_lib=yes
+		fi
+		;;
+	      pass_all)
+		valid_a_lib=yes
+		;;
+            esac
+	    if test "$valid_a_lib" != yes; then
+	      $echo
+	      $echo "*** Warning: Trying to link with static lib archive $deplib."
+	      $echo "*** I have the capability to make that library automatically link in when"
+	      $echo "*** you link to this library.  But I can only do this if you have a"
+	      $echo "*** shared version of the library, which you do not appear to have"
+	      $echo "*** because the file extensions .$libext of this argument makes me believe"
+	      $echo "*** that it is just a static archive that I should not used here."
+	    else
+	      $echo
+	      $echo "*** Warning: Linking the shared library $output against the"
+	      $echo "*** static library $deplib is not portable!"
+	      deplibs="$deplib $deplibs"
+	    fi
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$ladir" = "X$lib" && ladir="."
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	case $lib in
+	*/* | *\\*) . $lib ;;
+	*) . ./$lib ;;
+	esac
+
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	      exit $EXIT_FAILURE
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+	        case "$tmp_libs " in
+	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	        esac
+              fi
+	      tmp_libs="$tmp_libs $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  fi
+	fi # $installed = yes
+	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+		 test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath " in
+	      *" $dir "*) ;;
+	      *" $absdir "*) ;;
+	      *) temp_rpath="$temp_rpath $absdir" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes ; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  if test "$installed" = no; then
+	    notinst_deplibs="$notinst_deplibs $lib"
+	    need_relink=yes
+	  fi
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on
+	  # some systems (darwin)
+	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
+	    $echo
+	    if test "$linkmode" = prog; then
+	      $echo "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $echo "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $echo "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    realname="$2"
+	    shift; shift
+	    libname=`eval \\$echo \"$libname_spec\"`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw*)
+		major=`expr $current - $age`
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      $show "extracting exported symbol list from \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$extract_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      $show "generating import library for \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$old_archive_from_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a module then we can not link against
+		    # it, someone is ignoring the new warnings I added
+		    if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
+		      $echo "** Warning, lib $linklib is a module, not a shared library"
+		      if test -z "$old_library" ; then
+		        $echo
+		        $echo "** And there doesn't seem to be a static archive available"
+		        $echo "** The link will probably fail, sorry"
+		      else
+		        add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      $echo "$modename: configuration error: unsupported hardcode properties"
+	      exit $EXIT_FAILURE
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes && \
+		 test "$hardcode_minus_L" != yes && \
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+	        add="$inst_prefix_dir$libdir/$linklib"
+	      else
+	        add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    $echo
+	    $echo "*** Warning: This system can not link to static lib archive $lib."
+	    $echo "*** I have the capability to make that library automatically link in when"
+	    $echo "*** you link to this library.  But I can only do this if you have a"
+	    $echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      $echo "*** But as you try to build a module library, libtool will still create "
+	      $echo "*** a static module, that should work as long as the dlopening application"
+	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		$echo
+		$echo "*** However, this would only work if libtool was able to extract symbol"
+		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		$echo "*** not find such a program.  So, this module is probably useless."
+		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+		test "X$dir" = "X$deplib" && dir="."
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if grep "^installed=no" $deplib > /dev/null; then
+		  path="$absdir/$objdir"
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  if test -z "$libdir"; then
+		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		    exit $EXIT_FAILURE
+		  fi
+		  if test "$absdir" != "$libdir"; then
+		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+		  fi
+		  path="$absdir"
+		fi
+		depdepl=
+		case $host in
+		*-*-darwin*)
+		  # we do not want to link against static libs,
+		  # but need to link against shared
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$deplibdir/$depdepl" ; then
+		      depdepl="$deplibdir/$depdepl"
+	      	    elif test -f "$path/$depdepl" ; then
+		      depdepl="$path/$depdepl"
+		    else
+		      # Can't find it, oh well...
+		      depdepl=
+		    fi
+		    # do not add paths which are already there
+		    case " $newlib_search_path " in
+		    *" $path "*) ;;
+		    *) newlib_search_path="$newlib_search_path $path";;
+		    esac
+		  fi
+		  path=""
+		  ;;
+		*)
+		  path="-L$path"
+		  ;;
+		esac
+		;;
+	      -l*)
+		case $host in
+		*-*-darwin*)
+		  # Again, we only want to link against shared libraries
+		  eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+		  for tmp in $newlib_search_path ; do
+		    if test -f "$tmp/lib$tmp_libs.dylib" ; then
+		      eval depdepl="$tmp/lib$tmp_libs.dylib"
+		      break
+		    fi
+		  done
+		  path=""
+		  ;;
+		*) continue ;;
+		esac
+		;;
+	      *) continue ;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	      case " $deplibs " in
+	      *" $depdepl "*) ;;
+	      *) deplibs="$depdepl $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  tmp_libs="$tmp_libs $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
+      esac
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+	  exit $EXIT_FAILURE
+	else
+	  $echo
+	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
+	  $echo "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      if test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$2"
+	  number_minor="$3"
+	  number_revision="$4"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows|none)
+	    current=`expr $number_major + $number_minor`
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    current=`expr $number_major + $number_minor`
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	    $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$2"
+	  revision="$3"
+	  age="$4"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  minor_current=`expr $current + 1`
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    major=`expr $current - $age`
+	  else
+	    major=`expr $current - $age + 1`
+	  fi
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=.`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  major=`expr $current - $age`
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+      fi
+
+      if test "$mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$echo "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+	         if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+	         then
+		   continue
+		 fi
+	       fi
+	       removelist="$removelist $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	if test -n "$removelist"; then
+	  $show "${rm}r $removelist"
+	  $run ${rm}r $removelist
+	fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+      #	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+      #	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs -framework System"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+ 	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name=`expr $i : '-l\(.*\)'`
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    newdeplibs="$newdeplibs $i"
+		    i=""
+		    ;;
+		  esac
+	        fi
+		if test -n "$i" ; then
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    $echo
+		    $echo "*** Warning: dynamic linker does not accept needed library $i."
+		    $echo "*** I have the capability to make that library automatically link in when"
+		    $echo "*** you link to this library.  But I can only do this if you have a"
+		    $echo "*** shared version of the library, which I believe you do not have"
+		    $echo "*** because a test_compile did reveal that the linker did not use it for"
+		    $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      name=`expr $i : '-l\(.*\)'`
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+		$rm conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      newdeplibs="$newdeplibs $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval \\$echo \"$libname_spec\"`
+		    deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		    set dummy $deplib_matches
+		    deplib_match=$2
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      newdeplibs="$newdeplibs $i"
+		    else
+		      droppeddeps=yes
+		      $echo
+		      $echo "*** Warning: dynamic linker does not accept needed library $i."
+		      $echo "*** I have the capability to make that library automatically link in when"
+		      $echo "*** you link to this library.  But I can only do this if you have a"
+		      $echo "*** shared version of the library, which you do not appear to have"
+		      $echo "*** because a test_compile did reveal that the linker did not use this one"
+		      $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  $echo
+		  $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  $echo "*** make it link in!  You will probably need to install it or some"
+		  $echo "*** library that it depends on before this library will be fully"
+		  $echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name=`expr $a_deplib : '-l\(.*\)'`
+	    # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | ${SED} 10q \
+			 | $EGREP "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name=`expr $a_deplib : '-l\(.*\)'`
+	    # If $name is empty we are operating on a -L argument.
+	    if test -n "$name" && test "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval $echo \"$potent_lib\" 2>/dev/null \
+		        | ${SED} 10q \
+		        | $EGREP "$match_pattern_regex" > /dev/null; then
+		      newdeplibs="$newdeplibs $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	    -e 's/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+	    done
+	  fi
+	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
+	    | grep . >/dev/null; then
+	    $echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      $echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    $echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library is the System framework
+	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    $echo
+	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    $echo "*** a static module, that should work as long as the dlopening"
+	    $echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      $echo
+	      $echo "*** However, this would only work if libtool was able to extract symbol"
+	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      $echo "*** not find such a program.  So, this module is probably useless."
+	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    $echo "*** The inter-library dependencies that have been dropped here will be"
+	    $echo "*** automatically added whenever a program is linked with this library"
+	    $echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      $echo
+	      $echo "*** Since this library must not contain undefined symbols,"
+	      $echo "*** because either the platform does not support them or"
+	      $echo "*** it was explicitly requested with -no-undefined,"
+	      $echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      case $archive_cmds in
+	      *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
+	      *)      eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
+	      esac
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      eval cmd=\"$cmd\"
+	      if len=`expr "X$cmd" : ".*"` &&
+	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	        $show "$cmd"
+	        $run eval "$cmd" || exit $?
+	        skipped_export=false
+	      else
+	        # The command line is too long to execute in one step.
+	        $show "using reloadable object file for export list..."
+	        skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+		case " $convenience " in
+		*" $test_deplib "*) ;;
+		*)
+			tmp_deplibs="$tmp_deplibs $test_deplib"
+			;;
+		esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    libobjs="$libobjs $func_extract_archives_result"
+	  fi
+	fi
+	
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval test_cmds=\"$archive_expsym_cmds\"
+	  cmds=$archive_expsym_cmds
+	else
+	  eval test_cmds=\"$archive_cmds\"
+	  cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise.
+	  $echo "creating reloadable object files..."
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  output_la=`$echo "X$output" | $Xsed -e "$basename"`
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  delfiles=
+	  last_robj=
+	  k=1
+	  output=$output_objdir/$output_la-${k}.$objext
+	  # Loop over the list of objects to be linked.
+	  for obj in $save_libobjs
+	  do
+	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+	    if test "X$objlist" = X ||
+	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+		 test "$len" -le "$max_cmd_len"; }; then
+	      objlist="$objlist $obj"
+	    else
+	      # The command $test_cmds is almost too long, add a
+	      # command to the queue.
+	      if test "$k" -eq 1 ; then
+		# The first file doesn't have a previous command to add.
+		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+	      else
+		# All subsequent reloadable object files will link in
+		# the last one created.
+		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+	      fi
+	      last_robj=$output_objdir/$output_la-${k}.$objext
+	      k=`expr $k + 1`
+	      output=$output_objdir/$output_la-${k}.$objext
+	      objlist=$obj
+	      len=1
+	    fi
+	  done
+	  # Handle the remaining objects by creating one last
+	  # reloadable object file.  All subsequent reloadable object
+	  # files will link in the last one created.
+	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+	  if ${skipped_export-false}; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    libobjs=$output
+	    # Append the command to create the export file.
+	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+	  # Set up a command to remove the reloadable object files
+	  # after they are used.
+	  i=0
+	  while test "$i" -lt "$k"
+	  do
+	    i=`expr $i + 1`
+	    delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
+	  done
+
+	  $echo "creating a temporary reloadable object file: $output"
+
+	  # Loop through the commands generated above and execute them.
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $concat_cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    cmds=$archive_expsym_cmds
+	  else
+	    cmds=$archive_cmds
+	    fi
+	  fi
+
+	  # Append the command to remove the reloadable object files
+	  # to the just-reset $cmds.
+	  eval cmds=\"\$cmds~\$rm $delfiles\"
+	fi
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $show "$cmd"
+	  $run eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$mode" = relink; then
+	      $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      $show "${rm}r $gentop"
+	      $run ${rm}r "$gentop"
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
+      esac
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+	if test -n "$objs$old_deplibs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      cmds=$reload_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	eval cmd=\"$cmd\"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $run eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	cmds=$reload_cmds
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+	$show "${rm}r $gentop"
+	$run ${rm}r $gentop
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case $dlsyms in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    if test -n "$export_symbols_regex"; then
+	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$outputname.exp"
+	      $run $rm $export_symbols
+	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+	    else
+	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+	    $run eval '$echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" |
+		if sort -k 3 </dev/null >/dev/null 2>&1; then
+		  sort -k 3
+		else
+		  sort +2
+		fi |
+		uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+"
+
+	    case $host in
+	    *cygwin* | *mingw* )
+	  $echo >> "$output_objdir/$dlsyms" "\
+/* DATA imports from DLLs on WIN32 can't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs */
+struct {
+"
+	      ;;
+	    * )
+	  $echo >> "$output_objdir/$dlsyms" "\
+const struct {
+"
+	      ;;
+	    esac
+
+
+	  $echo >> "$output_objdir/$dlsyms" "\
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+	    esac;;
+	  *-*-hpux*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+          case $host in
+          *cygwin* | *mingw* )
+            if test -f "$output_objdir/${outputname}.def" ; then
+              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
+              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
+            else
+              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+             fi
+            ;;
+          * )
+            compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+            finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+            ;;
+          esac
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
+      fi
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	exit_status=$?
+
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case $dir in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$run $rm $output
+	# Link the executable and exit
+	$show "$link_command"
+	$run eval "$link_command" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+	case $progpath in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+            output_name=`basename $output`
+            output_path=`dirname $output`
+            cwrappersource="$output_path/$objdir/lt-$output_name.c"
+            cwrapper="$output_path/$output_name.exe"
+            $rm $cwrappersource $cwrapper
+            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+	    cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+/* -DDEBUG is fairly common in CFLAGS.  */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+            cat >> $cwrappersource <<EOF
+  newargz[0] = (char *) xstrdup("$SHELL");
+EOF
+
+            cat >> $cwrappersource <<"EOF"
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe");
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
+EOF
+
+            case $host_os in
+              mingw*)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",(char const **)newargz);
+EOF
+              ;;
+              *)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+              ;;
+            esac
+
+            cat >> $cwrappersource <<"EOF"
+  return 127;
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (
+        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+       ((st.st_mode & S_IXUSR) == S_IXUSR))
+      )
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
+char *
+find_executable (const char* wrapper)
+{
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
+
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
+#endif
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+          # we should really use a build-platform specific compiler
+          # here, but OTOH, the wrappers (shell script and this C one)
+          # are only useful if you want to execute the "real" binary.
+          # Since the "real" binary is built for $host, then this
+          # wrapper might as well be built for $host, too.
+          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+          ;;
+        esac
+        $rm $output
+        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$echo \"\$relink_command_output\" >&2
+	$rm \"\$progdir/\$file\"
+	exit $EXIT_FAILURE
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2*)
+	  $echo >> $output "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $echo >> $output "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \$*\"
+      exit $EXIT_FAILURE
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	generated="$generated $gentop"
+
+	func_extract_archives $gentop $addlibs
+	oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  $echo "copying selected object files to avoid basename conflicts..."
+
+	  if test -z "$gentop"; then
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "$mkdir $gentop"
+	    $run $mkdir "$gentop"
+	    exit_status=$?
+	    if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+	      exit $exit_status
+	    fi
+	  fi
+
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		counter=`expr $counter + 1`
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      $run ln "$obj" "$gentop/$newobj" ||
+	      $run cp "$obj" "$gentop/$newobj"
+	      oldobjs="$oldobjs $gentop/$newobj"
+	      ;;
+	    *) oldobjs="$oldobjs $obj" ;;
+	    esac
+	  done
+	fi
+
+	eval cmds=\"$old_archive_cmds\"
+
+	if len=`expr "X$cmds" : ".*"` &&
+	     test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  $echo "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  for obj in $save_oldobjs
+	  do
+	    oldobjs="$objlist $obj"
+	    objlist="$objlist $obj"
+	    eval test_cmds=\"$old_archive_cmds\"
+	    if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+	       test "$len" -le "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+	        RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+        eval cmd=\"$cmd\"
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		if test -z "$libdir"; then
+		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		  exit $EXIT_FAILURE
+		fi
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit $EXIT_FAILURE
+	      fi
+	      newdlfiles="$newdlfiles $libdir/$name"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit $EXIT_FAILURE
+	      fi
+	      newdlprefiles="$newdlprefiles $libdir/$name"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlfiles="$newdlfiles $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlprefiles="$newdlprefiles $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $rm $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $echo >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) 
+      	case " $install_prog " in
+	*[\\\ /]cp\ *) ;;
+	*) prev=$arg ;;
+	esac
+	;;
+      -g | -m | -o) prev=$arg ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit $EXIT_FAILURE
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	library_names=
+	old_library=
+	relink_command=
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  if test "$inst_prefix_dir" = "$destdir"; then
+	    $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP`
+	  else
+	    relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP`
+	  fi
+
+	  $echo "$modename: warning: relinking \`$file'" 1>&2
+	  $show "$relink_command"
+	  if $run eval "$relink_command"; then :
+	  else
+	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$srcname $destdir/$realname"
+	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+	  if test -n "$stripme" && test -n "$striplib"; then
+	    $show "$striplib $destdir/$realname"
+	    $run eval "$striplib $destdir/$realname" || exit $?
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      if test "$linkname" != "$realname"; then
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+	      fi
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  cmds=$postinstall_cmds
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    eval cmd=\"$cmd\"
+	    $show "$cmd"
+	    $run eval "$cmd" || {
+	      lt_exit=$?
+
+	      # Restore the uninstalled library and exit
+	      if test "$mode" = relink; then
+		$run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	      fi
+
+	      exit $lt_exit
+	    }
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	instname="$dir/$name"i
+	$show "$install_prog $instname $destdir/$name"
+	$run eval "$install_prog $instname $destdir/$name" || exit $?
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      file=`$echo $file|${SED} 's,.exe$,,'`
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin*|*mingw*)
+	    wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
+	  # If there is no directory component, then add one.
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$notinst_deplibs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case $lib in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
+	  # If there is no directory component, then add one.
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
+	  esac
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir=`func_mktempdir`
+	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway 
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+	    ;;
+	  esac
+	  ;;
+	esac
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	$show "$old_striplib $oldlib"
+	$run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=$old_postinstall_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	eval cmd=\"$cmd\"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  cmds=$finish_cmds
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    eval cmd=\"$cmd\"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit $EXIT_SUCCESS
+
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit $EXIT_FAILURE
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit $EXIT_FAILURE
+      fi
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+		$lt_var=\$save_$lt_var; export $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+	$echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+	dir=.
+	objdir="$origobjdir"
+      else
+	objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+	|| (test -h "$file") >/dev/null 2>&1 \
+	|| test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+	  case "$mode" in
+	  clean)
+	    case "  $library_names " in
+	    # "  " in the beginning catches empty $dlname
+	    *" $dlname "*) ;;
+	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    esac
+	     test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      cmds=$postuninstall_cmds
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      cmds=$old_postuninstall_cmds
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+	  # Read the .lo file
+	  . $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" \
+	     && test "$pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" \
+	     && test "$non_pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    file=`$echo $file|${SED} 's,.exe$,,'`
+	    noexename=`$echo $name|${SED} 's,.exe$,,'`
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    rmfiles="$rmfiles $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	    relink_command=
+	    . $dir/$noexename
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      rmfiles="$rmfiles $objdir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	$show "rmdir $dir"
+	$run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit $EXIT_FAILURE
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool at gnu.org>."
+  exit $EXIT_SUCCESS
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit $?
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+disable_libs=shared
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+disable_libs=static
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/missing b/missing
new file mode 100755
index 0000000..e7ef83a
--- /dev/null
+++ b/missing
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2003-09-02.23
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# 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 2, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake at gnu.org>."
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/modules/CW263.f b/modules/CW263.f
new file mode 100644
index 0000000..854a484
--- /dev/null
+++ b/modules/CW263.f
@@ -0,0 +1,887 @@
+      program CW263
+c
+c   Stream function wave theory code:
+c   * automatic selection of order
+c   * uniform current
+c   * returns proportion of limiting height
+c   j.r.chaplin at soton.ac.uk
+c
+c   Subroutine cw260 solves the wave.  Kinematics are then available
+c   through subtroutine kmts as illustrated below in the main program.
+c   Stores results in CW263.PSI in a format compatible with that used
+c      by CW6.FOR (24/3/99)
+c
+      character ans*1
+c
+   10 write(*,'(a)') ' Water depth (m)   = '
+      read*,d
+      write(*,'(a)') ' Period      (s)   = '
+      read*,t
+      write(*,'(a)') ' Wave height (m)   = '
+      read*,h
+      write(*,'(a)') ' Current     (m/s) = '
+      read*,u
+      nverb= 1
+c
+      call cw260(d,t,h,u,nverb,n,el)
+c
+   20 write(*,'(/a)')
+     :  ' (H)orizontal, (V)ertical, (S)urface, (N)ew wave, (Q)uit : '
+      read(*,'(a)') ans
+      goto (20,21,22,23,10,29) (index('HhVvSsNnQq',ans)+3)/2
+c
+c   Horizontal
+c
+   21 write(*,'(a)') ' y (m) = '
+      read*,yy
+      npt= 21
+      write(*,3)
+      do 31 i=1,npt
+      xx= el*(i-1)/float(npt-1)
+      tt= 0.0
+      call kmts(n,xx,yy,tt,uu,vv,ut,vt,du,dv,etah)
+      ans= ' '
+      if (yy.gt.etah) ans='*'
+   31 write(*,'(f9.3,8f8.3,1x,a)') xx,yy,uu,vv,ut,vt,du,dv,etah,ans
+      goto 20
+c
+c   Vertical
+c
+   22 write(*,'(a)') ' x/L = '
+      read*,xl
+      xx= xl*el
+      yy= 0.0
+      tt= 0.0
+      call kmts(n,xx,yy,tt,uu,vv,ut,vt,du,dv,etah)
+      npt= 21
+      write(*,3)
+      do 32 i=1,npt
+      yy= (d+etah)*(npt-i)/float(npt-1)-d
+      call kmts(n,xx,yy,tt,uu,vv,ut,vt,du,dv,etah)
+   32 write(*,'(f9.3,8f8.3,1x,1a)') xx,yy,uu,vv,ut,vt,du,dv,etah
+      goto 20
+c
+c   Free surface
+c
+   23 npt= 21
+      write(*,3)
+      do 33 i=1,npt
+      xx= el*(i-1)/float(npt-1)
+      yy= h
+      tt= 0.0
+      call kmts(n,xx,yy,tt,uu,vv,ut,vt,du,dv,etah)
+   33 write(*,'(f9.3,8f8.3)') xx,etah,uu,vv,ut,vt,du,dv,etah
+      goto 20
+c
+   29 stop
+    3 format('      x       y       u       v      ut   ',
+     :  '   vt      du      dv      eta')
+      end
+c
+c
+c
+      subroutine cw260(zd,zt,zh,zu,nverb,nfun,zel)
+c
+c  Input:  zd=depth; zt=period; zh=height; u=current; nverb=verbosity
+c  Output: nfun=order; zel=wavelength
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      real zd,zt,zh,zu,zel
+      double precision k
+      character itl*79,datim*22
+      common /one/ d,t,h,u,k
+     :       /two/ eta(nmax),c(nmax),amp(0:nmax)
+c
+      pi= 4*atan(1.0)
+c
+      d= zd
+      t= zt
+      hw= zh
+      u= zu
+c
+c  Get required solution order
+c
+      call wavecel(t,d,u,tr,cel)
+      call limit(hw,d,tr,rat,1)
+      dl0= d/(9.81*t*t/(2*pi))
+      a= 0.86/sqrt(dl0)
+      b= 7+2.2*log(dl0)
+      cc= 2.7-3*log(dl0)
+      nve= nint((a+b*rat+cc*rat**2)/2)*2
+      nve= nve+2
+      hb= hw/rat
+c
+      k= 2*pi/(cel*t)
+c
+c  Start with height=<Hb/2
+c    First step up orders; then heights ...
+c
+      if (nverb.ne.0) write(*,'(/2a)')
+     :   '      d       T       H       U    order  iter  ',
+     :   'rms error  code      L'
+      nfun = 6
+      h= min(hw,0.5*hb)
+      do 10 i=0,nmax
+   10 amp(i)= 0.0
+      amp(1)= h/2
+   12 continue
+      call cw261(nfun,iter,fsumsq,ifail)
+      if (ifail.eq.0) then
+         el= 2*pi/k
+         if (nverb.ne.0) write(*,'(a,4f8.3,i5,i7,1p1e12.3,0p,i5,f10.3)')
+     :      ' ',d,t,h,u,nfun,iter,fsumsq,ifail,el
+      else
+         if (nverb.ne.0) write(*,'(a,4f8.3,i5,i7,1p1e12.3,0p,i5)')
+     :      ' ',d,t,h,u,nfun,iter,fsumsq,ifail
+         stop
+      endif
+      if (nfun.lt.nve) then
+         nfun= nfun+2
+         goto 12
+      endif
+c
+      if (hw.gt.0.5*hb) then
+         fac= 1.1
+   11    hm= h
+         if (h*fac.gt.hw) then
+            h= hw
+            ilast= 1
+         else
+            h= h*fac
+            ilast= 0
+         endif
+         do 14 i=1,nfun-1
+   14    amp(i)= (h/hm)*amp(i)
+         call cw261(nfun,iter,fsumsq,ifail)
+         if (ifail.eq.0) then
+            el= 2*pi/k
+            if (nverb.ne.0)
+     :         write(*,'(a,4f8.3,i5,i7,1p1e12.3,0p,i5,f10.3)')
+     :         ' ',d,t,h,u,nfun,iter,fsumsq,ifail,el
+         else
+            if (nverb.ne.0) write(*,'(a,4f8.3,i5,i7,1p1e12.3,0p,i5)')
+     :         ' ',d,t,h,u,nfun,iter,fsumsq,ifail
+            stop
+         endif
+         if (ilast.ne.1) then
+            fac= 0.995*fac
+            goto 11
+         endif
+      endif
+      zel= 2*pi/k
+c
+c$$$      open(12,file='cw263.psi')
+c$$$      itl= 'Solved by CW263'
+c$$$      datim= 'Space for date & time:'
+c$$$      ver= 5.01
+c$$$      el0= 9.81*zt**2/(2*pi)
+c$$$      hl0= zh/el0
+c$$$      dl0= zd/el0
+c$$$      wl0= zel/el0
+c$$$      write(12,101) itl,datim,ver,hl0,dl0,wl0,zh,zd,zt,nfun-1,zu
+c$$$      write(12,102) (eta(i),c(i+1),i=1,nfun-1),eta(nfun)
+c$$$      write(12,107) (amp(i)/zh,i=0,nfun-1)
+c$$$      close(12)
+c
+  101 format(a/a,f10.2/3f16.10/3f16.10,i5,f16.10)
+  102 format(1p2e25.16)
+  107 format(1p1e25.16)
+c
+      return
+      end
+c
+c
+c
+      subroutine cw261(nfun,iter,fsumsq,ifail)
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      double precision k
+      dimension x(nmax),f(nmax),etas(2*nmax),bb(0:nmax)
+      common /one/ d,t,h,u,k
+     :       /two/ eta(nmax),c(nmax),amp(0:nmax)
+c
+      pi= 4*atan(1.0)
+c
+      do 10 i=1,nfun-2
+      th= (i-1)*pi/(nfun-1)
+      x(i)= 0.0
+      do 10 j=1,nfun-1
+   10 x(i)= x(i)+cos(j*th)*amp(j)
+      x(nfun-1)= k
+      jverb= 0
+      call gaf(nfun,nfun-1,x,f,fsumsq,jverb,iter,ifail)
+      if (ifail.eq.1) return
+      k= x(nfun-1)
+      do 11 i=1,nfun
+   11 etas(i)= eta(i)
+      do 12 i=1,nfun-1
+   12 etas(nfun+i)= eta(nfun-i)
+      call four(etas,2*nfun-2,amp,bb,nfun-1)
+      amp(nfun)= 0.0
+      bb(nfun)= 0.0
+      return
+      end
+c
+c
+c
+      subroutine lsfun(nfun,x,f,jac,sq,ifail)
+c
+c  Computes function errors and Jacobian
+c  x(1:nfun-1) = unknowns,  f(1:nfun) = functions
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      double precision k,jac,ks
+      dimension x(nmax),f(nmax),jac(nmax,nmax)
+      dimension dex(nmax,nmax),th(nmax),s(nmax),
+     :	chcs(nmax,nmax),chsn(nmax,nmax),shcs(nmax,nmax),shsn(nmax,nmax),
+     :	fu(nmax,nmax),df(nmax,nmax),a(nmax),da(nmax,nmax),
+     :  dax(nmax,nmax),dcx(nmax,nmax),dfx(nmax,nmax),
+     :	us(nmax),vs(nmax),dux(nmax,nmax),dvx(nmax,nmax)
+      common /one/ d,t,h,u,k
+     :       /two/ eta(nmax),c(nmax),amp(0:nmax)
+c
+      pi= 4*atan(1.0d0)
+      g= 9.81d0
+      ifail= 0
+      om= 2*pi/t
+c
+c  Get surface elevations
+c
+      do 40 i=1,nfun-2
+   40 eta(i)= x(i)
+      eta(nfun)= eta(1)-h
+      sm= 0.0
+      do 10 i=2,nfun-2
+   10 sm= sm+eta(i)
+      eta(nfun-1)= -sm-(eta(1)+eta(nfun))/2
+      do 11 i=2,nfun
+      if (eta(i).gt.eta(i-1)+5*h/nfun) then
+	 ifail= 1
+c        write(*,'(7f11.3)') (eta(m),m=1,nfun-1)
+	 return
+      endif
+   11 continue
+      k= x(nfun-1)
+c
+c  Get dex(i,j) = d(eta(i))/d(eta(j)), 1 <= j <= nfun-2
+c
+      do 18 i=1,nfun
+      dex(i,nfun-1)= 0.0d0
+      do 18 j=1,nfun-2
+      if (i.lt.nfun-1) then
+	 if (i.eq.j) then
+	    dex(i,j)= 1.0d0
+	 else
+	    dex(i,j)= 0.0d0
+	 endif
+      else if (i.eq.nfun-1) then
+	 dex(i,j)= -1.0d0
+      else if (i.eq.nfun) then
+	 if (j.eq.1) then
+	    dex(i,j)= 1.0d0
+	 else
+	    dex(i,j)= 0.0d0
+	 endif
+      endif
+   18 continue
+c
+c  Set some useful functions
+c
+      do 23 i=1,nfun
+      th(i)= pi*(i-1)/float(nfun-1)
+      s(i)= d+eta(i)
+      ks= k*s(i)
+      do 23 n=1,nfun
+      ch= cosh(n*ks)
+      sh= sinh(n*ks)
+      cs= cos(n*th(i))
+      sn= sin(n*th(i))
+      chcs(i,n)= ch*cs
+      shsn(i,n)= sh*sn
+      chsn(i,n)= ch*sn
+   23 shcs(i,n)= sh*cs
+c
+c  Get normalised stream function coefficients a(j)
+c
+      do 12 i=1,nfun
+      fu(i,1)= k*s(i)
+      df(i,1)= k
+      do 12 j=2,nfun
+      n= j-1
+      fu(i,j)= shcs(i,n)
+   12 df(i,j)= chcs(i,n)*n*k
+      call trans2(nfun,fu,df,a,da)
+c
+c  Get dax(i,j) = d(a(i))/d(eta(j)), 1 <=j <= nfun-2
+c
+      do 41 i=1,nfun
+      do 41 j=1,nfun-2
+      dij= 0.0
+      do 42 n=1,nfun
+   42 dij= dij+da(i,n)*dex(n,j)
+   41 dax(i,j)= dij
+c
+c   Get dax(i,nfun-1) = d(a(i))/dk
+c
+      do 19 i=1,nfun
+      sm= 0.0
+      do 13 m=1,nfun
+   13 sm= sm+da(i,m)*s(m)/k
+   19 dax(i,nfun-1)= sm
+c
+c  De-normalise to get correct reverse mean flow
+c
+      a1k2= a(1)*k**2
+      r= (u*k-om)/a1k2
+      do 24 i=1,nfun
+      c(i)= a(i)*r
+      do 24 j=1,nfun-1
+      drx= -(u*k-om)*dax(1,j)*(k/a1k2)**2
+      if (j.eq.nfun-1) then
+         drx= drx+u/a1k2-2*a(1)*k*(u*k-om)/a1k2**2
+      endif
+   24 dcx(i,j)= r*dax(i,j)+a(i)*drx
+c
+c  Get surface velocities and functions
+c
+      do 14 i=1,nfun
+      su= k*c(1)
+      sv= 0.0d0
+      do 15 n=1,nfun-1
+      su= su+n*k*c(n+1)*chcs(i,n)
+   15 sv= sv+n*k*c(n+1)*shsn(i,n)
+      us(i)= su
+   14 vs(i)= sv
+      sm= 0.0d0
+      do 16 i=1,nfun
+      f(i)= (us(i)**2+vs(i)**2)/(2*g)+eta(i)
+   16 sm= sm+f(i)
+      sm= sm/float(nfun)
+      sq= 0.0d0
+      do 17 i=1,nfun
+      f(i)= f(i)-sm
+   17 sq= sq+f(i)**2
+      sq= sqrt(sq/nfun)/h
+c
+c  Get d(u(i))/d(eta(j)) and d(u(i))/dk
+c
+      do 20 i=1,nfun
+      do 21 j=1,nfun-2
+      su= k*dcx(1,j)
+      sv= 0.0d0
+      do 22 n=1,nfun-1
+      su= su+n*k*dcx(n+1,j)*chcs(i,n)+(n*k)**2*c(n+1)*shcs(i,n)*dex(i,j)
+   22 sv= sv+n*k*dcx(n+1,j)*shsn(i,n)+(n*k)**2*c(n+1)*chsn(i,n)*dex(i,j)
+      dux(i,j)= su
+   21 dvx(i,j)= sv
+      j= nfun-1
+      su= c(1)+k*dcx(1,j)
+      sv= 0.0d0
+      do 25 n=1,nfun-1
+      su= su+(c(n+1)+k*dcx(n+1,j))*n*chcs(i,n)+
+     :	    n**2*k*s(i)*c(n+1)*shcs(i,n)
+   25 sv= sv+(c(n+1)+k*dcx(n+1,j))*n*shsn(i,n)+
+     :	    n**2*k*s(i)*c(n+1)*chsn(i,n)
+      dux(i,j)= su
+   20 dvx(i,j)= sv
+c
+c  Get derivatives of functions
+c
+      do 44 i=1,nfun
+      do 44 j=1,nfun-1
+   44 dfx(i,j)= (us(i)*dux(i,j)+vs(i)*dvx(i,j))/g+dex(i,j)
+c
+      do 45 j=1,nfun-1
+      sm= 0.0
+      do 46 i=1,nfun
+   46 sm= sm+dfx(i,j)
+      sm= sm/nfun
+      do 45 i=1,nfun
+   45 jac(i,j)= dfx(i,j)-sm
+c
+      return
+      end
+c
+c
+c
+      subroutine trans2(n,f,df,a,da)
+c
+c  Gramm-Schmidt orthogonalisation with derivatives
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      dimension f(nmax,nmax),df(nmax,nmax),a(nmax),da(nmax,nmax)
+      dimension c(nmax,nmax),b(nmax),cr(nmax,nmax),g(nmax,nmax),
+     :   dly(nmax),dc(nmax,nmax),br(nmax,nmax),db(nmax)
+      do 10 i=1,n
+      do 10 j=1,n
+   10 c(i,j)= 0.0d0
+c
+      st= 0.0d0
+      do 54 i=1,n
+   54 st= st+f(i,1)**2
+      st= dsqrt(st)
+c
+      do 16 i=1,n
+   16 g(i,1)= f(i,1)/st
+      c(1,1)= st
+      do 18 k=2,n
+      km= k-1
+      do 29 j=1,km
+      st= 0.0d0
+      do 20 i=1,n
+   20 st= st+g(i,j)*f(i,k)
+   29 c(j,k)= st
+      c(k,k)= 1.0d0
+      do 21 i=1,n
+      st= 0.0d0
+      do 22 j=1,km
+   22 st= st+c(j,k)*g(i,j)
+   21 g(i,k)= f(i,k)-st
+      st= 0.0d0
+      do 50 i=1,n
+   50 st= st+g(i,k)**2
+      st= dsqrt(st)
+      do 52 i=1,n
+   52 g(i,k)= g(i,k)/st
+      c(k,k)= st
+      do 200 j=1,km
+      st= 0.0d0
+      do 202 i=1,n
+  202 st= st+g(i,j)*g(i,k)
+  200 db(j)= st
+      do 204 i=1,n
+      st= 0.0d0
+      do 206 j=1,km
+  206 st= st+db(j)*g(i,j)
+  204 g(i,k)=g(i,k)-st
+   18 continue
+      do 24 j=1,n
+      st= 0.0d0
+      do 26 i=1,n
+   26 st= st+g(i,j)
+   24 b(j)= st
+      st= 0.0d0
+      do 208 i=1,n
+      sb= 0.0d0
+      do 210 j=1,n
+  210 sb= sb+b(j)*g(i,j)
+  208 st= st+(sb-1.0d0)**2
+      call trinv(n,c,cr)
+      do 28 i=1,n
+      st= 0.0d0
+      do 30 j=1,n
+   30 st= st+cr(i,j)*b(j)
+   28 a(i)= st
+      st= 0.0d0
+      do 72 i=1,n
+      sb= 0.0d0
+      do 74 j=1,n
+   74 sb= sb+a(j)*f(i,j)
+   72 st= st+(sb-1.0d0)**2
+      st= dsqrt(st/float(n))
+      do 80 k=1,n
+      do 81 i=1,n
+      do 81 j=1,n
+   81 dc(i,j)= 0.0d0
+      dly(1)= 2.0d0*f(k,1)*df(k,1)
+      dc(1,1)= 0.5d0*dly(1)/c(1,1)
+      do 82 j=2,n
+   82 dc(1,j)= (f(k,j)*df(k,1)+df(k,j)*f(k,1))/c(1,1)
+     :	    -0.5d0*dly(1)*c(1,j)/c(1,1)**2
+      do 84 l=2,n
+      lm= l-1
+      st= 0.0d0
+      do 86 m=1,lm
+   86 st= st+c(m,l)*dc(m,l)
+      dly(l)= 2.0d0*(f(k,l)*df(k,l)-st)
+      dc(l,l)= 0.5d0*dly(l)/c(l,l)
+      if (l.eq.n) goto 84
+      lp= l+1
+      do 85 m=lp,n
+      st= 0.0d0
+      do 90 j=1,lm
+   90 st= st+c(j,m)*dc(j,l)+dc(j,m)*c(j,l)
+   85 dc(l,m)= (f(k,m)*df(k,l)+df(k,m)*f(k,l))/c(l,l)
+     :	    -st/c(l,l)-0.5d0*dly(l)*c(l,m)/c(l,l)**2
+   84 continue
+      do 92 l=1,n
+      do 92 m=1,n
+      st= 0.0d0
+      do 96 j=1,n
+   96 st= st+g(l,j)*dc(j,m)
+   92 br(l,m)= -st
+      do 94 m=1,n
+   94 br(k,m)= br(k,m)+df(k,m)
+      do 32 j=1,n
+      sb= 0.0d0
+      do 34 i=1,n
+      st= 0.0d0
+      do 36 l=1,n
+   36 st= st+br(i,l)*cr(l,j)
+   34 sb= sb+st
+   32 db(j)= sb
+      do 38 i=1,n
+      st= db(i)
+      do 40 j=1,n
+   40 st= st-dc(i,j)*a(j)
+   38 dly(i)= st
+      do 42 i=1,n
+      st= 0.0d0
+      do 44 j=1,n
+   44 st= st+cr(i,j)*dly(j)
+   42 da(i,k)= st
+   80 continue
+      return
+      end
+c
+c
+c
+      subroutine trinv(n,c,w)
+c
+c  3-diagonal system solver
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      dimension c(nmax,nmax),w(nmax,nmax)
+      do 10 i=1,n
+      do 10 j=1,n
+   10 w(i,j)= 0.0d0
+      do 12 jj=1,n
+      j= n+1-jj
+      w(j,j)= 1.0d0
+      if (j.eq.1) goto 12
+      k= j-1
+      do 13 ii=1,k
+      i= k-ii+1
+      sum= 0.0d0
+      do 14 l=1,ii
+      m= n+2-jj-l
+   14 sum= sum+c(i,m)*w(m,j)/c(m,m)
+   13 w(i,j)= -sum
+   12 continue
+      do 16 i=1,n
+      sum= c(i,i)
+      do 16 j=1,n
+   16 w(i,j)= w(i,j)/sum
+      return
+      end
+c
+c
+c
+      subroutine wavecel(ta,d,u,tr,c)
+c
+c  Linear theory C by series approximation for waves on a current u
+c    d  = still water depth
+c    ta = absolute period (fixed reference frame)
+c    tr = relative period (reference frame moving with the current)
+c    c  = celerity (reference frame moving with the current)
+c
+      implicit double precision (a-h,o-z)
+      pi= 4*atan(1.0d0)
+      g= 9.81
+      sigma= 2*pi/ta
+      y= sigma*sigma*d/g
+      a= 1.0/(1.0+y*(0.6667+y*(0.3556+y*(0.1608+y*(0.06321+
+     :	y*(0.02744+y*0.01))))))
+      c= dsqrt((d*g)/(y+a))
+      if (abs(u).lt.1.0d-6) then
+	 tr= ta
+	 return
+      else
+	 el= c*ta
+	 iter= 0
+   10	 tr= el/(el/ta-u)
+         elp= (g*tr**2/(2*pi))*tanh(2*pi*d/el)
+	 del= elp-el
+	 el= el+del*0.4
+	 if (abs(del/el).gt.1.0d-6) then
+	    iter= iter+1
+	    if (iter.eq.100) then
+               write(*,'(a)') ' WAVECEL error'
+	       stop
+	    endif
+	    goto 10
+	 endif
+	 tr= el/(el/ta-u)
+	 c= el/tr
+	 return
+      endif
+      end
+c
+c
+c
+      subroutine slpds(a,b,n,cc)
+c
+c  Linear system solution
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      dimension a(nmax,nmax),b(nmax),cc(nmax)
+      n1= n-1
+      do 100 k=1,n1
+      c= a(k,k)
+      k1= k+1
+      if (abs(c).lt.1.0d-10) then
+         write(*,'(a,i5)') ' Matrix error 1: ',k
+         stop
+      endif
+      do 4 j=k1,n
+    4 a(k,j)= a(k,j)/c
+      b(k)= b(k)/c
+      do 10 i=k1,n
+      c= a(i,k)
+      do 5 j=k1,n
+    5 a(i,j)= a(i,j)-c*a(k,j)
+   10 b(i)= b(i)-c*b(k)
+  100 continue
+      if (abs(a(n,n)).lt.1.0d-10) then
+         write(*,'(a,i5)') ' Matrix error 2: ',n
+         stop
+      endif
+      b(n)= b(n)/a(n,n)
+      do 200 l=1,n1
+      k= n-l
+      k1= k+1
+      do 200 j=k1,n
+  200 b(k)= b(k)-a(k,j)*b(j)
+      do 300 i=1,n
+  300 cc(i)= b(i)
+      return
+      end
+c
+c
+c
+      subroutine gaf(nf,nv,xc,fvecc,fsumsq,nverb,iter,ifail)
+c
+c   Non-linear system error minimisation
+c   ifail =  0: OK
+c            1: looks hopeless
+c            2: poor convergence
+c
+      implicit double precision (a-h,o-z)
+      parameter (nmax=25)
+      dimension xc(nmax),fvecc(nmax)
+      dimension fjacc(nmax,nmax),
+     :   aa(nmax,nmax),bb(nmax),cc(nmax),xcm(nmax)
+c
+      iter = 0
+      icalls= 0
+      orf= 2.0/nf
+      fsumsm= 100.0
+c
+   15 do 16 i=1,nv
+   16 xcm(i)= xc(i)
+   19 call lsfun(nf,xc,fvecc,fjacc,fsumsq,ifl)
+      icalls= icalls+1
+      if ((fsumsq.gt.fsumsm.and.iter.gt.1).or.ifl.ne.0) then
+         if (orf.lt.0.05) then
+            ifail= 1
+            return
+         endif
+         orf= 0.8*orf
+         iter= max(iter-1,0)
+         do 18 i=1,nv
+   18    xc(i)= xcm(i)
+         fsumsm= 100.0
+         goto 19
+      endif
+      call monit(nf,fvecc,icalls,nverb)
+c
+      do 10 i=1,nv
+      do 10 j=1,nv
+      ra= 0.0d0
+      do 11 l=1,nf
+   11 ra= ra+fjacc(l,i)*fjacc(l,j)
+   10 aa(i,j)= ra
+c
+      do 12 i=1,nv
+      ra= 0.0d0
+      do 13 l=1,nf
+   13 ra= ra+fvecc(l)*fjacc(l,i)
+   12 bb(i)= -ra
+c
+      call slpds(aa,bb,nv,cc)
+c
+      dxmax= 0.0d0
+      do 14 i=1,nv
+      dxmax= max(dxmax,abs(cc(i)))
+   14 xc(i)= xc(i)+orf*cc(i)
+c
+      iter= iter+1
+      fsumsm= fsumsq
+      orf= min(1.0d0,orf*1.1)
+c
+      if (iter.ge.50.and.fsumsq.lt.1.0d-4) then
+         ifail= 2
+         return
+      endif
+      if (iter.ge.50) then
+         ifail= 1
+         return
+      endif
+      if (fsumsq.gt.1.0d-6) goto 15
+      ifail= 0
+      return
+      end
+c
+c
+c
+      subroutine monit(nfun,f,icalls,nverb)
+      implicit double precision (a-h,o-z)
+      double precision k
+      parameter (nmax=25)
+      dimension f(nmax)
+      common /one/ d,t,h,u,k
+     :       /two/ eta(nmax),c(nmax),amp(0:nmax)
+c
+c  Outputs monitoring data
+c
+      if (nverb.eq.0) return
+      sm= 0.0d0
+      do 10 i=1,nfun
+   10 sm=sm+f(i)**2
+      sq= sqrt(sm/nfun)/h
+      write(*,'(/i11,1p1e11.3)') icalls,sq
+      write(*,'(1p7e11.3)') (eta(i),i=1,nfun)
+      return
+      end
+c
+c
+c
+      subroutine limit(h,d,t,rat,nverb)
+      double precision h,d,t,rat
+c
+c  Estimates H/(limiting height for d and t) = rat
+c
+      dimension dl0(18),hl0(18)
+      data dl0/2,0.578,0.440,0.356,0.293,0.243,0.201,0.166,0.1359,
+     :         0.1100,0.0876,0.0686,0.0524,0.0390,0.0277,0.01879,
+     :         0.01168,0.00638/
+      data hl0/0.1682,0.1665,0.1613,0.1531,0.1423,0.1298,0.1159,
+     :         0.1017,0.0873,0.0735,0.0605,0.0487,0.0380,0.0289,
+     :         0.0208,0.01440,0.00911,0.00501/
+      pi= 4*atan(1.0)
+      el0= 9.81*t**2/(2*pi)
+      ha= h/el0
+      da= d/el0
+      if (da.gt.dl0(1)) then
+         rat= ha/hl0(1)
+      else if (da.lt.dl0(18)) then
+         rat= ha/(0.8*da)
+      else
+         do 10 i=2,18
+         if (dl0(i).lt.da) goto 11
+   10    continue
+   11    x1= log(dl0(i))
+         x2= log(dl0(i-1))
+         y1= log(hl0(i))
+         y2= log(hl0(i-1))
+         r= (log(da)-x1)/(x2-x1)
+         hb= exp(y1+r*(y2-y1))
+         rat= ha/hb
+      endif
+c
+c      if (nverb.ne.0.or.rat.gt.1.0) then
+c         write(*,'(a,f5.3)') ' H/Hb              = ',rat
+c      endif
+      if (rat.gt.1.0) stop
+c
+      return
+      end
+c
+c
+c
+      subroutine four(f,n,a,b,nb)
+c
+c  Fourier analysis
+c
+      implicit double precision (a-h,o-z)
+      dimension a(0:nb),b(0:nb),f(n)
+      pi= 4*atan(1.0d0)
+      rn= 2.0d0/n
+      t= 2*pi/n
+      c= cos(t)
+      s= sin(t)
+      vk= 0.0d0
+      vl= -1.0d0
+      do 10 k=0,nb 
+      t= c*vk  
+      ck= t-vl 
+      vl= vk   
+      vk= ck+t 
+      t= ck+ck 
+      ul= 0.0d0
+      um= f(n) 
+      do 12 mm=3,n 
+      m= n+2-mm
+      u0= ul   
+      ul= um   
+   12 um= t*ul-u0+f(m) 
+      a(k)= (ck*um-ul+f(1))*rn 
+   10 b(k)= s*vl*um*rn 
+      a(0)= a(0)*0.5d0
+      if (2*nb.ne.n) return
+      a(nb)= a(nb)*0.5d0
+      b(nb)= 0.0d0
+      return   
+      end
+c
+c
+c
+      subroutine kmts(nfun,xx,yy,tt,uu,vv,ut,vt,du,dv,etah)
+c
+c   Computes
+c        horizontal and vertical velocity components (u,v)
+c        horizontal and vertical local acceleration components (ut,vt)
+c        horizontal and vertical total acceleration components (du,dv)
+c        water surface elevation (etah)
+c   at t=tt; x=xx; y=yy.
+c   If yy>eta kinematics are returned at the free surface
+c
+      implicit double precision (a-h,o-z)
+      real xx,yy,tt,uu,vv,ut,vt,du,dv,etah
+      parameter (nmax=25)
+      double precision k,ks
+      common /one/ d,t,h,u,k
+     :       /two/ eta(nmax),c(nmax),amp(0:nmax)
+      pi=4*atan(1.0d0)
+      om= 2*pi/t
+      theta= k*xx-om*tt
+c
+      etah= 0.0
+      do 11 i=1,nfun-1
+   11 etah= etah+cos(i*theta)*amp(i)
+c
+      ks= k*(d+min(yy,etah))
+      s1= 0.0
+      s2= 0.0
+      s3= 0.0
+      s4= 0.0
+c
+      do 10 i=1,nfun-1
+      ip= i+1
+      ch= cosh(i*ks)
+      sh= sinh(i*ks)
+      cs= cos(i*theta)
+      sn= sin(i*theta)
+      s1= s1+i*ch*cs*c(ip)
+      s2= s2+i*sh*sn*c(ip)
+      s3= s3+i*i*ch*sn*c(ip)
+   10 s4= s4+i*i*sh*cs*c(ip)
+      uu=  u+k*s1
+      vv=  k*s2
+      ut=  k*om*s3
+      vt= -k*om*s4
+      ux= -k*k*s3
+      vx=  k*k*s4
+      uy=  vx
+      vy= -ux
+      du= ut+uu*ux+vv*uy
+      dv= vt+uu*vx+vv*vy
+c
+      return
+      end
+
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644
index 0000000..d0d899e
--- /dev/null
+++ b/modules/Makefile.am
@@ -0,0 +1,137 @@
+## Process this file with automake to produce Makefile.in
+
+#SUBDIRS = RStarTree fes2004 wavewatch
+SUBDIRS = wavewatch
+
+AM_CPPFLAGS = -DGFS_MODULES_DIR=\"$(libdir)/gerris\"
+
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) \
+           -DG_LOG_DOMAIN=\"Gfs-modules\" $(GTS_CFLAGS)
+
+if HAS_LIBPROJ
+MAP = libmap2D.la libmap3D.la libmap2D3.la
+endif
+#if BUILD_TIDE
+#TIDE = libtide2D.la libtide3D.la libtide2D3.la
+#endif
+if BUILD_STOKES
+STOKES = libstokes2D.la libstokes3D.la
+endif
+if BUILD_WAVEWATCH
+WAVEWATCH = libwavewatch2D.la
+endif
+
+pkglib_LTLIBRARIES = \
+	$(MAP) \
+	$(TIDE) \
+	$(STOKES) \
+	$(WAVEWATCH)
+#	libterrain2D.la \
+#	libterrain3D.la \
+#	libterrain2D3.la 
+
+#bin_PROGRAMS = \
+#	xyz2rsurface \
+#	rsurfacequery \
+#	rsurfacedraw
+
+EXTRA_DIST = \
+	map.mod \
+	tide.mod \
+	terrain.mod \
+	stokes.mod \
+	wavewatch.mod
+
+BUILT_SOURCES = \
+	map.c \
+	tide.c \
+	terrain.c \
+	stokes.c \
+	wavewatch.c
+
+AM_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+
+libmap3D_la_SOURCES = map.c
+libmap3D_la_LIBADD = -lproj
+libmap2D_la_SOURCES = map.c
+libmap2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+libmap2D_la_LIBADD = -lproj
+libmap2D3_la_SOURCES = map.c
+libmap2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+libmap2D3_la_LIBADD = -lproj
+
+#libterrain3D_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain3D_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain3D_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libterrain2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+#libterrain2D_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain2D_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain2D_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libterrain2D3_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+#libterrain2D3_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain2D3_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libtide3D_la_SOURCES = tide.c
+#libtide3D_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS)
+#libtide3D_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+#libtide2D_la_SOURCES = tide.c
+#libtide2D_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS) -DFTT_2D=1
+#libtide2D_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+#libtide2D3_la_SOURCES = tide.c
+#libtide2D3_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS) -DFTT_2D3=1
+#libtide2D3_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+
+libstokes3D_la_SOURCES = stokes.c CW263.f
+libstokes3D_la_CFLAGS = $(AM_CFLAGS)
+libstokes2D_la_SOURCES = stokes.c CW263.f
+libstokes2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+
+libwavewatch2D_la_SOURCES = wavewatch.c
+libwavewatch2D_la_LIBADD = -Lwavewatch -lwavewatch -L/usr/lib/gcc/i486-linux-gnu/4.2 -lgfortran
+libwavewatch2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1 \
+  -DW3SRCE=`nm wavewatch/libwavewatch.a | grep w3srce | awk '{ if ($$2 == "T") print $$3; }'` \
+  -DGFSW3INIT=`nm wavewatch/libwavewatch.a | grep gfsw3_init | awk '{ if ($$2 == "T") print $$3; }'`
+libwavewatch2D_la_DEPENDENCIES = wavewatch/libwavewatch.a
+
+#xyz2rsurface_SOURCES = xyz2rsurface.c rsurface.c rsurface.h
+#xyz2rsurface_LDADD = -LRStarTree -lcSmRST
+#xyz2rsurface_CFLAGS = $(AM_CFLAGS)
+#xyz2rsurface_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#rsurfacequery_SOURCES = rsurfacequery.c rsurface.c rsurface.h
+#rsurfacequery_LDADD = -LRStarTree -lcSmRST
+#rsurfacequery_CFLAGS = $(AM_CFLAGS)
+#rsurfacequery_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#rsurfacedraw_SOURCES = rsurfacedraw.c rsurface.c rsurface.h
+#rsurfacedraw_LDADD = -LRStarTree -lcSmRST
+#rsurfacedraw_CFLAGS = $(AM_CFLAGS)
+#rsurfacedraw_DEPENDENCIES = RStarTree/libcSmRST.la
+
+if HAVE_MODULES
+%.c : %.mod
+	@echo "/* $@" > $@
+	@echo " * This is a generated file.  Please modify \`$<'" >> $@
+	@echo " */" >> $@
+	@echo "#line 1 \""$<"\"" >> $@
+	@cat $< >> $@
+else
+%.c : %.mod
+	@echo "/* $@" > $@
+	@echo " * This is a generated file.  Please modify \`$<'" >> $@
+	@echo " */" >> $@
+	@echo "#line 1 \""$<"\"" >> $@
+	@replace="s/g_module_check_init/gfs_init_`basename $< .mod`/g";\
+	 sed $$replace < $< >> $@
+endif
+
+clean-generic:
+	$(RM) $(BUILT_SOURCES)
+
+dist-hook:
+	for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/modules/Makefile.in b/modules/Makefile.in
new file mode 100644
index 0000000..97cb124
--- /dev/null
+++ b/modules/Makefile.in
@@ -0,0 +1,927 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = modules
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+libmap2D_la_DEPENDENCIES =
+am_libmap2D_la_OBJECTS = libmap2D_la-map.lo
+libmap2D_la_OBJECTS = $(am_libmap2D_la_OBJECTS)
+libmap2D_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libmap2D_la_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ at HAS_LIBPROJ_TRUE@am_libmap2D_la_rpath = -rpath $(pkglibdir)
+libmap2D3_la_DEPENDENCIES =
+am_libmap2D3_la_OBJECTS = libmap2D3_la-map.lo
+libmap2D3_la_OBJECTS = $(am_libmap2D3_la_OBJECTS)
+libmap2D3_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libmap2D3_la_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ at HAS_LIBPROJ_TRUE@am_libmap2D3_la_rpath = -rpath $(pkglibdir)
+libmap3D_la_DEPENDENCIES =
+am_libmap3D_la_OBJECTS = map.lo
+libmap3D_la_OBJECTS = $(am_libmap3D_la_OBJECTS)
+ at HAS_LIBPROJ_TRUE@am_libmap3D_la_rpath = -rpath $(pkglibdir)
+libstokes2D_la_LIBADD =
+am_libstokes2D_la_OBJECTS = libstokes2D_la-stokes.lo CW263.lo
+libstokes2D_la_OBJECTS = $(am_libstokes2D_la_OBJECTS)
+ at BUILD_STOKES_TRUE@am_libstokes2D_la_rpath = -rpath $(pkglibdir)
+libstokes3D_la_LIBADD =
+am_libstokes3D_la_OBJECTS = libstokes3D_la-stokes.lo CW263.lo
+libstokes3D_la_OBJECTS = $(am_libstokes3D_la_OBJECTS)
+ at BUILD_STOKES_TRUE@am_libstokes3D_la_rpath = -rpath $(pkglibdir)
+am_libwavewatch2D_la_OBJECTS = libwavewatch2D_la-wavewatch.lo
+libwavewatch2D_la_OBJECTS = $(am_libwavewatch2D_la_OBJECTS)
+libwavewatch2D_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libwavewatch2D_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+ at BUILD_WAVEWATCH_TRUE@am_libwavewatch2D_la_rpath = -rpath $(pkglibdir)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+F77COMPILE = $(F77) $(AM_FFLAGS) $(FFLAGS)
+LTF77COMPILE = $(LIBTOOL) --tag=F77 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS)
+F77LD = $(F77)
+F77LINK = $(LIBTOOL) --tag=F77 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libmap2D_la_SOURCES) $(libmap2D3_la_SOURCES) \
+	$(libmap3D_la_SOURCES) $(libstokes2D_la_SOURCES) \
+	$(libstokes3D_la_SOURCES) $(libwavewatch2D_la_SOURCES)
+DIST_SOURCES = $(libmap2D_la_SOURCES) $(libmap2D3_la_SOURCES) \
+	$(libmap3D_la_SOURCES) $(libstokes2D_la_SOURCES) \
+	$(libstokes3D_la_SOURCES) $(libwavewatch2D_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+
+#SUBDIRS = RStarTree fes2004 wavewatch
+SUBDIRS = wavewatch
+AM_CPPFLAGS = -DGFS_MODULES_DIR=\"$(libdir)/gerris\"
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) \
+           -DG_LOG_DOMAIN=\"Gfs-modules\" $(GTS_CFLAGS)
+
+ at HAS_LIBPROJ_TRUE@MAP = libmap2D.la libmap3D.la libmap2D3.la
+#if BUILD_TIDE
+#TIDE = libtide2D.la libtide3D.la libtide2D3.la
+#endif
+ at BUILD_STOKES_TRUE@STOKES = libstokes2D.la libstokes3D.la
+ at BUILD_WAVEWATCH_TRUE@WAVEWATCH = libwavewatch2D.la
+pkglib_LTLIBRARIES = \
+	$(MAP) \
+	$(TIDE) \
+	$(STOKES) \
+	$(WAVEWATCH)
+
+#	libterrain2D.la \
+#	libterrain3D.la \
+#	libterrain2D3.la 
+
+#bin_PROGRAMS = \
+#	xyz2rsurface \
+#	rsurfacequery \
+#	rsurfacedraw
+EXTRA_DIST = \
+	map.mod \
+	tide.mod \
+	terrain.mod \
+	stokes.mod \
+	wavewatch.mod
+
+BUILT_SOURCES = \
+	map.c \
+	tide.c \
+	terrain.c \
+	stokes.c \
+	wavewatch.c
+
+AM_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+
+libmap3D_la_SOURCES = map.c
+libmap3D_la_LIBADD = -lproj
+libmap2D_la_SOURCES = map.c
+libmap2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+libmap2D_la_LIBADD = -lproj
+libmap2D3_la_SOURCES = map.c
+libmap2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+libmap2D3_la_LIBADD = -lproj
+
+#libterrain3D_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain3D_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain3D_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libterrain2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+#libterrain2D_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain2D_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain2D_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libterrain2D3_la_SOURCES = terrain.c rsurface.c rsurface.h
+#libterrain2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+#libterrain2D3_la_LIBADD = -LRStarTree -lcSmRST
+#libterrain2D3_la_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#libtide3D_la_SOURCES = tide.c
+#libtide3D_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS)
+#libtide3D_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+#libtide2D_la_SOURCES = tide.c
+#libtide2D_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS) -DFTT_2D=1
+#libtide2D_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+#libtide2D3_la_SOURCES = tide.c
+#libtide2D3_la_CFLAGS = $(AM_CFLAGS) $(GSL_CFLAGS) -DFTT_2D3=1
+#libtide2D3_la_LIBADD = -Lfes2004 -lfes -lnetcdf $(GSL_LIBS)
+libstokes3D_la_SOURCES = stokes.c CW263.f
+libstokes3D_la_CFLAGS = $(AM_CFLAGS)
+libstokes2D_la_SOURCES = stokes.c CW263.f
+libstokes2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+libwavewatch2D_la_SOURCES = wavewatch.c
+libwavewatch2D_la_LIBADD = -Lwavewatch -lwavewatch -L/usr/lib/gcc/i486-linux-gnu/4.2 -lgfortran
+libwavewatch2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1 \
+  -DW3SRCE=`nm wavewatch/libwavewatch.a | grep w3srce | awk '{ if ($$2 == "T") print $$3; }'` \
+  -DGFSW3INIT=`nm wavewatch/libwavewatch.a | grep gfsw3_init | awk '{ if ($$2 == "T") print $$3; }'`
+
+libwavewatch2D_la_DEPENDENCIES = wavewatch/libwavewatch.a
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .f .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu modules/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+	@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+	}
+
+uninstall-pkglibLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+clean-pkglibLTLIBRARIES:
+	-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+	@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libmap2D.la: $(libmap2D_la_OBJECTS) $(libmap2D_la_DEPENDENCIES) 
+	$(libmap2D_la_LINK) $(am_libmap2D_la_rpath) $(libmap2D_la_OBJECTS) $(libmap2D_la_LIBADD) $(LIBS)
+libmap2D3.la: $(libmap2D3_la_OBJECTS) $(libmap2D3_la_DEPENDENCIES) 
+	$(libmap2D3_la_LINK) $(am_libmap2D3_la_rpath) $(libmap2D3_la_OBJECTS) $(libmap2D3_la_LIBADD) $(LIBS)
+libmap3D.la: $(libmap3D_la_OBJECTS) $(libmap3D_la_DEPENDENCIES) 
+	$(LINK) $(am_libmap3D_la_rpath) $(libmap3D_la_OBJECTS) $(libmap3D_la_LIBADD) $(LIBS)
+libstokes2D.la: $(libstokes2D_la_OBJECTS) $(libstokes2D_la_DEPENDENCIES) 
+	$(F77LINK) $(am_libstokes2D_la_rpath) $(libstokes2D_la_OBJECTS) $(libstokes2D_la_LIBADD) $(LIBS)
+libstokes3D.la: $(libstokes3D_la_OBJECTS) $(libstokes3D_la_DEPENDENCIES) 
+	$(F77LINK) $(am_libstokes3D_la_rpath) $(libstokes3D_la_OBJECTS) $(libstokes3D_la_LIBADD) $(LIBS)
+libwavewatch2D.la: $(libwavewatch2D_la_OBJECTS) $(libwavewatch2D_la_DEPENDENCIES) 
+	$(libwavewatch2D_la_LINK) $(am_libwavewatch2D_la_rpath) $(libwavewatch2D_la_OBJECTS) $(libwavewatch2D_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libmap2D3_la-map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libmap2D_la-map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libstokes2D_la-stokes.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libstokes3D_la-stokes.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libwavewatch2D_la-wavewatch.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+libmap2D_la-map.lo: map.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmap2D_la_CFLAGS) $(CFLAGS) -MT libmap2D_la-map.lo -MD -MP -MF $(DEPDIR)/libmap2D_la-map.Tpo -c -o libmap2D_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libmap2D_la-map.Tpo $(DEPDIR)/libmap2D_la-map.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='map.c' object='libmap2D_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmap2D_la_CFLAGS) $(CFLAGS) -c -o libmap2D_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+
+libmap2D3_la-map.lo: map.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmap2D3_la_CFLAGS) $(CFLAGS) -MT libmap2D3_la-map.lo -MD -MP -MF $(DEPDIR)/libmap2D3_la-map.Tpo -c -o libmap2D3_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libmap2D3_la-map.Tpo $(DEPDIR)/libmap2D3_la-map.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='map.c' object='libmap2D3_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmap2D3_la_CFLAGS) $(CFLAGS) -c -o libmap2D3_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+
+libstokes2D_la-stokes.lo: stokes.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstokes2D_la_CFLAGS) $(CFLAGS) -MT libstokes2D_la-stokes.lo -MD -MP -MF $(DEPDIR)/libstokes2D_la-stokes.Tpo -c -o libstokes2D_la-stokes.lo `test -f 'stokes.c' || echo '$(srcdir)/'`stokes.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libstokes2D_la-stokes.Tpo $(DEPDIR)/libstokes2D_la-stokes.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stokes.c' object='libstokes2D_la-stokes.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstokes2D_la_CFLAGS) $(CFLAGS) -c -o libstokes2D_la-stokes.lo `test -f 'stokes.c' || echo '$(srcdir)/'`stokes.c
+
+libstokes3D_la-stokes.lo: stokes.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstokes3D_la_CFLAGS) $(CFLAGS) -MT libstokes3D_la-stokes.lo -MD -MP -MF $(DEPDIR)/libstokes3D_la-stokes.Tpo -c -o libstokes3D_la-stokes.lo `test -f 'stokes.c' || echo '$(srcdir)/'`stokes.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libstokes3D_la-stokes.Tpo $(DEPDIR)/libstokes3D_la-stokes.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stokes.c' object='libstokes3D_la-stokes.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstokes3D_la_CFLAGS) $(CFLAGS) -c -o libstokes3D_la-stokes.lo `test -f 'stokes.c' || echo '$(srcdir)/'`stokes.c
+
+libwavewatch2D_la-wavewatch.lo: wavewatch.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwavewatch2D_la_CFLAGS) $(CFLAGS) -MT libwavewatch2D_la-wavewatch.lo -MD -MP -MF $(DEPDIR)/libwavewatch2D_la-wavewatch.Tpo -c -o libwavewatch2D_la-wavewatch.lo `test -f 'wavewatch.c' || echo '$(srcdir)/'`wavewatch.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libwavewatch2D_la-wavewatch.Tpo $(DEPDIR)/libwavewatch2D_la-wavewatch.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='wavewatch.c' object='libwavewatch2D_la-wavewatch.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwavewatch2D_la_CFLAGS) $(CFLAGS) -c -o libwavewatch2D_la-wavewatch.lo `test -f 'wavewatch.c' || echo '$(srcdir)/'`wavewatch.c
+
+.f.o:
+	$(F77COMPILE) -c -o $@ $<
+
+.f.obj:
+	$(F77COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.f.lo:
+	$(LTF77COMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-hook
+check-am: all-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(pkglibdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \
+	mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+	ctags-recursive install install-am install-strip \
+	tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-generic clean-libtool \
+	clean-pkglibLTLIBRARIES ctags ctags-recursive dist-hook \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkglibLTLIBRARIES install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am uninstall-pkglibLTLIBRARIES
+
+
+#xyz2rsurface_SOURCES = xyz2rsurface.c rsurface.c rsurface.h
+#xyz2rsurface_LDADD = -LRStarTree -lcSmRST
+#xyz2rsurface_CFLAGS = $(AM_CFLAGS)
+#xyz2rsurface_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#rsurfacequery_SOURCES = rsurfacequery.c rsurface.c rsurface.h
+#rsurfacequery_LDADD = -LRStarTree -lcSmRST
+#rsurfacequery_CFLAGS = $(AM_CFLAGS)
+#rsurfacequery_DEPENDENCIES = RStarTree/libcSmRST.la
+
+#rsurfacedraw_SOURCES = rsurfacedraw.c rsurface.c rsurface.h
+#rsurfacedraw_LDADD = -LRStarTree -lcSmRST
+#rsurfacedraw_CFLAGS = $(AM_CFLAGS)
+#rsurfacedraw_DEPENDENCIES = RStarTree/libcSmRST.la
+
+ at HAVE_MODULES_TRUE@%.c : %.mod
+ at HAVE_MODULES_TRUE@	@echo "/* $@" > $@
+ at HAVE_MODULES_TRUE@	@echo " * This is a generated file.  Please modify \`$<'" >> $@
+ at HAVE_MODULES_TRUE@	@echo " */" >> $@
+ at HAVE_MODULES_TRUE@	@echo "#line 1 \""$<"\"" >> $@
+ at HAVE_MODULES_TRUE@	@cat $< >> $@
+ at HAVE_MODULES_FALSE@%.c : %.mod
+ at HAVE_MODULES_FALSE@	@echo "/* $@" > $@
+ at HAVE_MODULES_FALSE@	@echo " * This is a generated file.  Please modify \`$<'" >> $@
+ at HAVE_MODULES_FALSE@	@echo " */" >> $@
+ at HAVE_MODULES_FALSE@	@echo "#line 1 \""$<"\"" >> $@
+ at HAVE_MODULES_FALSE@	@replace="s/g_module_check_init/gfs_init_`basename $< .mod`/g";\
+ at HAVE_MODULES_FALSE@	 sed $$replace < $< >> $@
+
+clean-generic:
+	$(RM) $(BUILT_SOURCES)
+
+dist-hook:
+	for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/map.mod b/modules/map.mod
new file mode 100644
index 0000000..3947296
--- /dev/null
+++ b/modules/map.mod
@@ -0,0 +1,180 @@
+/* Gerris - The GNU Flow Solver                       (-*-C-*-)
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <proj_api.h>
+#include "simulation.h"
+#include "map.h"
+
+/* GfsMapProjection: Header */
+
+typedef struct _GfsMapProjection         GfsMapProjection;
+
+struct _GfsMapProjection {
+  /*< private >*/
+  GfsMap parent;
+  projPJ pj;
+  gdouble cosa, sina;
+
+  /*< public >*/
+  gdouble lon, lat, angle;
+};
+
+#define GFS_MAP_PROJECTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsMapProjection,\
+					         gfs_map_projection_class ())
+#define GFS_IS_MAP_PROJECTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_map_projection_class ()))
+
+GfsMapClass * gfs_map_projection_class  (void);
+
+/* GfsMapProjection: Object */
+
+static void gfs_map_projection_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_map_projection_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GtsFileVariable var[] = {
+    {GTS_DOUBLE, "lon",    TRUE},
+    {GTS_DOUBLE, "lat",    TRUE},
+    {GTS_DOUBLE, "angle",  TRUE},
+    {GTS_NONE}
+  };
+  GfsMapProjection * map = GFS_MAP_PROJECTION (*o);
+  var[0].data = &map->lon;
+  var[1].data = &map->lat;
+  var[2].data = &map->angle;
+
+  gts_file_assign_variables (fp, var);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  map->cosa = cos (map->angle*DEG_TO_RAD);
+  map->sina = sin (map->angle*DEG_TO_RAD);
+
+  char * parms[] = {
+    "proj=lcc", /* Lambert Conformal Conic */
+    NULL, NULL, NULL, NULL
+  };
+  parms[1] = g_strdup_printf ("lon_0=%lf", map->lon);
+  parms[2] = g_strdup_printf ("lat_0=%lf", map->lat);
+  parms[3] = g_strdup_printf ("lat_1=%lf", map->lat);
+  parms[4] = g_strdup_printf ("lat_2=%lf", map->lat);
+  map->pj = pj_init (sizeof(parms)/sizeof(char *), parms);
+  if (!map->pj)
+    gts_file_error (fp, "cannot initialise projection");
+  g_free (parms[1]);
+  g_free (parms[2]);
+  g_free (parms[3]);
+  g_free (parms[4]);
+}
+
+static void gfs_map_projection_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_map_projection_class ())->parent_class->write) (o, fp);
+  GfsMapProjection * map = GFS_MAP_PROJECTION (o);
+  fprintf (fp, " { lon = %.8g lat = %.8g angle = %g }",
+	   map->lon, map->lat, map->angle);
+}
+
+static void gfs_map_projection_destroy (GtsObject * object)
+{
+  if (GFS_MAP_PROJECTION (object)->pj)
+    pj_free (GFS_MAP_PROJECTION (object)->pj);
+  (* GTS_OBJECT_CLASS (gfs_map_projection_class ())->parent_class->destroy) (object);
+}
+
+static void projection_transform (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  projLP idata;
+  projXY odata;
+  GfsMapProjection * m = GFS_MAP_PROJECTION (map);
+  idata.u = src->x*DEG_TO_RAD;
+  idata.v = src->y*DEG_TO_RAD;
+  odata = pj_fwd (idata, m->pj);
+  dest->x = odata.u*m->cosa - odata.v*m->sina;
+  dest->y = odata.v*m->cosa + odata.u*m->sina;
+  dest->z = src->z;
+}
+
+static void projection_inverse (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  projLP odata;
+  projXY idata;
+  GfsMapProjection * m = GFS_MAP_PROJECTION (map);
+  idata.u = src->x*m->cosa + src->y*m->sina;
+  idata.v = src->y*m->cosa - src->x*m->sina;
+  odata = pj_inv (idata, GFS_MAP_PROJECTION (map)->pj);
+  dest->x = odata.u*RAD_TO_DEG;
+  dest->y = odata.v*RAD_TO_DEG;
+  dest->z = src->z;
+}
+
+static void gfs_map_projection_class_init (GfsMapClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_map_projection_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_map_projection_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_map_projection_destroy;
+}
+
+static void gfs_map_projection_init (GfsMapProjection * object)
+{
+  /* Wellington */
+  object->lon = 174.777222;
+  object->lat = -41.288889;
+  object->angle = 0.; object->cosa = 1.; object->sina = 0.;
+  object->pj = NULL;
+  GFS_MAP (object)->transform = projection_transform;
+  GFS_MAP (object)->inverse = projection_inverse;
+}
+
+GfsMapClass * gfs_map_projection_class (void)
+{
+  static GfsMapClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_map_projection_info = {
+      "GfsMapProjection",
+      sizeof (GfsMapProjection),
+      sizeof (GfsMapClass),
+      (GtsObjectClassInitFunc) gfs_map_projection_class_init,
+      (GtsObjectInitFunc) gfs_map_projection_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_map_class ()),
+				  &gfs_map_projection_info);
+  }
+
+  return klass;
+}
+
+/* Initialize module */
+
+/* only define gfs_module_name for "official" modules (i.e. those installed in
+   GFS_MODULES_DIR) */
+const gchar gfs_module_name[] = "map";
+const gchar * g_module_check_init (void);
+
+const gchar * g_module_check_init (void)
+{
+  gfs_map_projection_class ();
+  return NULL;
+}
diff --git a/modules/rsurface.c b/modules/rsurface.c
new file mode 100644
index 0000000..c00dfc7
--- /dev/null
+++ b/modules/rsurface.c
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <string.h>
+#include "RStarTree/RStarTree.h"
+#include "rsurface.h"
+
+/* RSurface */
+
+struct _RSurface {
+  RSTREE t;
+  char * name;
+};
+
+RSurface * r_surface_new (const char * fname, int size, FILE * fp)
+{
+  return NULL;
+}
+
+RSurface * r_surface_open (const char * fname, const char * mode, int size)
+{
+  RSurface * rt = malloc (sizeof (RSurface));
+  if (!strcmp (mode, "w")) {
+    RemoveRST (fname);
+    if (!CreateRST (fname, size, FALSE)) {
+      free (rt);
+      return NULL;
+    }
+  }
+  rt->t = NULL;
+  if (!OpenRST (&rt->t, fname, !strcmp (mode, "w") ? "rw" : "r")) {
+    free (rt);
+    return NULL;
+  }
+  rt->name = malloc (sizeof (char)*(strlen (fname) + 1));
+  strcpy (rt->name, fname);
+  return rt;
+}
+
+void r_surface_close (RSurface * rt)
+{
+  CloseRST (&rt->t);
+  free (rt->name);
+  free (rt);
+}
+
+int r_surface_insert  (RSurface * rt, double p[3], int id)
+{
+  typrect rect;
+  typinfo info;
+  boolean inserted;
+  rect[0].l = p[0]; rect[0].h = p[0];
+  rect[1].l = p[1]; rect[1].h = p[1];
+  info.height = p[2];
+  return (InsertRecord (rt->t, rect, &info, &inserted) && inserted);
+}
+
+void r_surface_query (RSurface * rt, 
+		      double a[2], double b[2], double c[2], double d[2],
+		      RSurfaceQuery q, void * user_data)
+{
+}
+
+static boolean Intersects (RSTREE R,
+			   typrect RSTrect,
+			   typrect queryrect,
+			   typrect unused)
+{
+  int maxdim= NumbOfDim -1;
+  boolean inter;
+  int d;
+  
+  d= -1;
+  do {
+    d++;
+    inter= RSTrect[d].l <= queryrect[d].h &&
+           RSTrect[d].h >= queryrect[d].l;
+  } while (inter && d != maxdim);
+  return inter;
+}
+
+static void ManageQuery (RSTREE R,
+			 typrect rectangle,
+			 refinfo infoptr,
+			 void ** data,
+			 boolean *modify,
+			 boolean *finish)
+{
+  RSurfaceQuery q = data[0];
+  double p[3];
+  p[0] = rectangle[0].l; p[1] = rectangle[1].l;
+  p[2] = infoptr->height;
+  (*q) (p, data[1]);
+  *modify = FALSE;
+  *finish = FALSE;
+}
+
+void r_surface_query_region (RSurface * rt, 
+			     double min[2], double max[2],
+			     RSurfaceQuery q, void * user_data)
+{
+  typrect rect, unused;
+  rect[0].l = min[0]; rect[0].h = max[0];
+  rect[1].l = min[1]; rect[1].h = max[1];
+  void * data[2];
+  data[0] = q;
+  data[1] = user_data;
+  RegionQuery (rt->t, rect, unused, Intersects, Intersects, ManageQuery, data);
+}
+
+void r_surface_sum_init (RSurfaceSum * sum)
+{
+  memset (sum, 0, sizeof (RSurfaceSum));
+  sum->Hmin = 1e30;
+  sum->Hmax = - 1e30;
+}
+
+/**
+ * Fills @sum using @rect to normalise the results i.e. the sums are
+ * expressed in a coordinate system centered on 
+ * (rect[0].l + rect[0].h, rect[1].l + rect[1].h)/2 
+ * and scaled by 
+ * MAX(rect[0].h - rect[0].l, rect[1].h - rect[1].l).
+ */
+void r_surface_query_region_sum (RSurface * rt,
+				 RSurfaceCheck includes,
+				 RSurfaceCheck intersects,
+				 void * data,
+				 RSurfaceRect rect,
+				 RSurfaceSum * sum)
+{
+  RegionQueryInfo (rt->t, (Check) includes, (Check) intersects, data, (typinterval *) rect,
+		   (typdirinfo *) sum);
+}
+
+const char * r_surface_name (RSurface * rt)
+{
+  return rt->name;
+}
+
+void r_surface_update (RSurface * rt)
+{
+  Update (rt->t);
+}
diff --git a/modules/rsurface.h b/modules/rsurface.h
new file mode 100644
index 0000000..4eedfc9
--- /dev/null
+++ b/modules/rsurface.h
@@ -0,0 +1,52 @@
+/* padding on 32 bits systems (to match automatic 64 bits padding) */
+
+#if defined (__LP64__) || defined (__64BIT__) || defined (_LP64) || (__WORDSIZE == 64)
+  #define PADDING_32_BITS
+#else
+  #define PADDING_32_BITS int padding
+#endif
+
+typedef struct _RSurface RSurface;
+
+typedef struct { /* needs to be identical to typdirinfo in RStarTree.h */
+  double m01, m02, m03;
+  double m11, m13;
+  double m22, m23, m33;
+  double m44, m55, m66, m77;
+  double m67, m76;
+  double H0, H1, H2, H3, H4;
+  double H5, H6;
+  float Hmin, Hmax;
+  int n;
+  PADDING_32_BITS;
+} RSurfaceSum;
+
+typedef struct {
+  float l, h;
+} RSurfaceInterval;
+
+typedef RSurfaceInterval  RSurfaceRect[2];
+
+typedef int (* RSurfaceCheck) (RSurfaceRect rect, void * data, int depth);
+
+RSurface * r_surface_new      (const char * fname, int size, FILE * fp);
+RSurface * r_surface_open     (const char * fname, const char * mode, int size);
+void       r_surface_update   (RSurface * rt);
+void       r_surface_close    (RSurface * rt);
+int        r_surface_insert   (RSurface * rt, double p[3], int id);
+
+typedef int (* RSurfaceQuery) (double p[3], void * user_data);
+void       r_surface_query    (RSurface * rt, 
+			       double a[2], double b[2], double c[2], double d[2],
+			       RSurfaceQuery q, void * user_data);
+void       r_surface_query_region (RSurface * rt, 
+				   double min[2], double max[2],
+				   RSurfaceQuery q, void * user_data);
+void       r_surface_sum_init (RSurfaceSum * sum);
+void       r_surface_query_region_sum (RSurface * rt,
+				       RSurfaceCheck includes,
+				       RSurfaceCheck intersects,
+				       void * data,
+				       RSurfaceRect rect,
+				       RSurfaceSum * sum);
+const char * r_surface_name (RSurface * rt);
diff --git a/modules/rsurfacedraw.c b/modules/rsurfacedraw.c
new file mode 100644
index 0000000..adf7c75
--- /dev/null
+++ b/modules/rsurfacedraw.c
@@ -0,0 +1,150 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+#include "ftt.h"
+#include "rsurface.h"
+
+typedef struct {
+  FILE ** fp;
+  double * ratio;
+  int * size;
+  char * name, * ext;
+  int maxdepth;
+} Params;
+
+static int includes (RSurfaceRect RSTrect, Params * p, int depth)
+{
+  if (RSTrect[0].l == RSTrect[0].h && RSTrect[1].l == RSTrect[1].h)
+    p->size[depth]++;
+  return 0;
+}
+
+#define MAXEXT 10
+
+static int intersects (RSurfaceRect RSTrect, Params * p, int depth)
+{
+  if (p->fp[depth] == NULL) {
+    snprintf (p->ext, MAXEXT, "-l%d", depth);
+    p->fp[depth] = fopen (p->name, "w");
+  }
+  fprintf (p->fp[depth], "%g %g\n%g %g\n%g %g\n%g %g\n%g %g\n\n",
+	   RSTrect[0].l, RSTrect[1].l,
+	   RSTrect[0].h, RSTrect[1].l,
+	   RSTrect[0].h, RSTrect[1].h,
+	   RSTrect[0].l, RSTrect[1].h,
+	   RSTrect[0].l, RSTrect[1].l);
+  double w = RSTrect[0].h - RSTrect[0].l, h = RSTrect[1].h - RSTrect[1].l;
+  double ratio = 1e10;
+  if (w > 0. && h > 0.)
+    ratio = w > h ? w/h : h/w;
+  p->ratio[depth] += ratio;
+  p->size[depth]++;
+  return (depth < p->maxdepth);
+}
+
+int main (int argc, char** argv)
+{
+  int c = 0;
+  int verbose = 0, gnuplot = 0;
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"gnuplot", no_argument, NULL, 'g'},
+      {"verbose", no_argument, NULL, 'v'},
+      {"help", no_argument, NULL, 'h'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "vhg",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "vhg"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'g': /* gnuplot */
+      gnuplot = 1;
+      break;
+    case 'v': /* verbose */
+      verbose = 1;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+	       "Usage: rsurfacedraw [OPTION] BASENAME MAXDEPTH\n"
+	       "\n"
+	       "Draws gnuplot representation of the bounding boxes of the R*-tree.\n"
+	       "\n"
+	       "  -g    --gnuplot     write gnuplot commands on standard output\n"
+	       "  -v    --verbose     display statistics\n"
+	       "  -h    --help        display this help and exit\n"
+	       "\n"
+	       "Report bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `rsurfacedraw --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+  if (optind >= argc) { /* missing BASENAME */
+    fprintf (stderr, 
+	     "rsurfacedraw: missing BASENAME\n"
+	     "Try `rsurfacedraw --help' for more information.\n");
+    return 1; /* failure */
+  }
+  if (optind + 1 >= argc) { /* missing MAXDEPTH */
+    fprintf (stderr, 
+	     "rsurfacedraw: missing MAXDEPTH\n"
+	     "Try `rsurfacedraw --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+  RSurface * rs = r_surface_open (argv[optind], "r", 0);
+  RSurfaceRect rect = {{-0.5,-0.5},{0.5,0.5}};
+  RSurfaceSum s;
+  Params p;
+  p.maxdepth = atoi (argv[optind + 1]);
+  p.name = malloc (sizeof (char)*(strlen (argv[optind]) + MAXEXT + 1));
+  strcpy (p.name, argv[optind]);
+  p.ext = &p.name[strlen (p.name)];
+  p.fp = calloc (p.maxdepth + 1, sizeof (FILE *));
+  p.size = calloc (p.maxdepth + 1, sizeof (int));
+  p.ratio = calloc (p.maxdepth + 1, sizeof (double));
+  r_surface_sum_init (&s);
+  r_surface_query_region_sum (rs, (RSurfaceCheck) includes, (RSurfaceCheck) intersects, &p, 
+			      rect, &s);
+  r_surface_close (rs);
+
+  if (verbose) {
+    int i;
+    for (i = 1; i <= p.maxdepth; i++)
+      if (p.size[i] > 0) {
+	fprintf (stderr, "level %d: %d\n", i, p.size[i]);
+	if (i < p.maxdepth && p.size[i + 1] > 0)
+	  fprintf (stderr, "\taverage ratio: %g average # of entries: %g\n",
+		   p.ratio[i]/p.size[i],
+		   p.size[i + 1]/(double) p.size[i]);
+	else
+	  fputc ('\n', stderr);
+      }
+  }
+  
+  if (gnuplot) {
+    int i;
+    printf ("set size ratio -1\n");
+    printf ("plot '%s-l1' w l t 'Level 1'", argv[optind]);
+    for (i = 2; i <= p.maxdepth; i++)
+      if (p.size[i] > 0)
+	printf (", '%s-l%d' w l t 'Level %d'", argv[optind], i, i);
+    putchar ('\n');
+  }
+
+  return 0.;
+}
diff --git a/modules/rsurfacequery.c b/modules/rsurfacequery.c
new file mode 100644
index 0000000..5ff7be8
--- /dev/null
+++ b/modules/rsurfacequery.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "rsurface.h"
+
+static int query (double p[3], void * data)
+{
+  printf ("%.8f %.8f %g\n", p[0], p[1], p[2]);
+  return 0;
+}
+
+int main (int argc, char** argv)
+{
+  if (argc != 2) {
+    fprintf (stderr, "Usage: %s basename\n", argv[0]);
+    return -1;
+  }
+
+  RSurface * rs = r_surface_open (argv[1], "r", 0);
+  if (rs == NULL) {
+    fprintf (stderr, "rsurfacequery: could not open `%s'\n", argv[1]);
+    return -1;
+  }    
+
+  double min[2], max[2];
+  int count = 0;
+  while (scanf ("%lf %lf %lf %lf", &min[0], &min[1], &max[0], &max[1]) == 4) {
+    r_surface_query_region (rs, min, max, query, NULL);
+    if (count > 0 && count % 1000 == 0)
+      fprintf (stderr, "\r%d", count);
+    count++;
+  }
+  if (count >= 1000)
+    fputc ('\n', stderr);
+  r_surface_close (rs);
+
+  return 0.;
+}
diff --git a/modules/stokes.mod b/modules/stokes.mod
new file mode 100644
index 0000000..93f2e61
--- /dev/null
+++ b/modules/stokes.mod
@@ -0,0 +1,192 @@
+/* Gerris - The GNU Flow Solver                       (-*-C-*-)
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+#include <stdlib.h>
+#include <math.h>
+#include "event.h"
+#include "solid.h"
+
+extern void cw260_ (const float * zd,
+		    const float * zt, 
+		    const float * zh, 
+		    const float * zu, 
+		    const int * nverb, 
+		    int * nfun, 
+		    float * zel);
+
+extern void kmts_  (const int * nfun,
+		    const float * xx,
+		    const float * yy,
+		    const float * tt,
+		    float * uu, 
+		    float * vv,
+		    float * ut,
+		    float * vt,
+		    float * du,
+		    float * dv,
+		    float * etah);
+
+/* GfsInitStokesWave: Header */
+
+typedef struct _GfsInitStokesWave         GfsInitStokesWave;
+
+struct _GfsInitStokesWave {
+  /*< private >*/
+  GfsGenericInit parent;
+  
+  /*< public >*/
+  gdouble steepness, depth;
+};
+
+#define GFS_INIT_STOKES_WAVE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsInitStokesWave,\
+					         gfs_init_stokes_wave_class ())
+
+GfsGenericInitClass * gfs_init_stokes_wave_class  (void);
+
+/* GfsInitStokesWave: Object */
+
+#define WAVELENGTH 100. /* metres */
+
+static int order = 0;
+
+static void gfs_init_stokes_wave_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsInitStokesWave * w = GFS_INIT_STOKES_WAVE (*o);
+  GtsFileVariable var[] = {
+    {GTS_DOUBLE, "depth",     TRUE},
+    {GTS_DOUBLE, "steepness", TRUE},
+    {GTS_NONE}
+  };
+  var[0].data = &w->depth;
+  var[1].data = &w->steepness;
+  gts_file_assign_variables (fp, var);  
+  if (fp->type == GTS_ERROR)
+    return;
+
+  float zd = WAVELENGTH*w->depth, zh = w->steepness*WAVELENGTH/M_PI, zu = 0., l;
+  int nverb = 0;
+  
+  float min = 1., max = 100., zt = (min + max)/2.;
+  do {
+    cw260_ (&zd, &zt, &zh, &zu, &nverb, &order, &l);
+    fprintf (stderr, "# order: %d wavelength: %g period: %g\n", 
+	     order, l, zt);
+    if (l > WAVELENGTH)
+      max = zt;
+    if (l < WAVELENGTH)
+      min = zt;
+    zt = (min + max)/2.;
+  } while (fabs (l - WAVELENGTH) > 1e-4);
+}
+
+static void gfs_init_stokes_wave_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class->write) 
+      (o, fp);
+
+  fprintf (fp, " { depth = %g steepness = %g }\n",
+	   GFS_INIT_STOKES_WAVE (o)->depth, 
+	   GFS_INIT_STOKES_WAVE (o)->steepness);
+}
+
+static void init_velocity (FttCell * cell, GfsVariable ** velocity)
+{
+  FttVector p;
+  gfs_cell_cm (cell, &p);
+  float x = (p.x + 0.5)*WAVELENGTH, y = p.y*WAVELENGTH, t = 0., u, v, ut, vt, du, dv, etah;
+  kmts_ (&order, &x, &y, &t, &u, &v, &ut, &vt, &du, &dv, &etah);
+  GFS_VALUE (cell, velocity[0]) = u/sqrt(WAVELENGTH*9.81);
+  GFS_VALUE (cell, velocity[1]) = v/sqrt(WAVELENGTH*9.81);
+}
+
+static gdouble stokes_height (gdouble x, gdouble y, gdouble z, gdouble t)
+{
+  float xx = (x + 0.5)*WAVELENGTH, yy = WAVELENGTH, u, v, ut, vt, du, dv, etah, t1 = 0.;
+  kmts_ (&order, &xx, &yy, &t1, &u, &v, &ut, &vt, &du, &dv, &etah);
+  return etah/WAVELENGTH - y;
+}
+
+static gboolean gfs_init_stokes_wave_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_stokes_wave_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsVariable ** velocity = gfs_domain_velocity (GFS_DOMAIN (sim));
+    GfsVariable * t = gfs_variable_from_name (GFS_DOMAIN (sim)->variables, "T");
+    g_assert (velocity);
+    g_assert (t);
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) init_velocity, velocity);
+    GfsSurface * surface = GFS_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+    surface->f = gfs_function_spatial_new (gfs_function_spatial_class (), stokes_height);
+    gfs_object_simulation_set (surface->f, sim);
+    gfs_domain_init_fraction (GFS_DOMAIN (sim), GFS_GENERIC_SURFACE (surface), t);
+    gts_object_destroy (GTS_OBJECT (surface));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_init_stokes_wave_class_init (GfsGenericInitClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_init_stokes_wave_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_init_stokes_wave_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_init_stokes_wave_write;
+}
+
+static void gfs_init_stokes_wave (GfsInitStokesWave * w)
+{
+  w->depth = 0.5;
+  w->steepness = 0.3;
+}
+
+GfsGenericInitClass * gfs_init_stokes_wave_class (void)
+{
+  static GfsGenericInitClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_stokes_wave_info = {
+      "GfsInitStokesWave",
+      sizeof (GfsInitStokesWave),
+      sizeof (GfsGenericInitClass),
+      (GtsObjectClassInitFunc) gfs_init_stokes_wave_class_init,
+      (GtsObjectInitFunc) gfs_init_stokes_wave,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_init_stokes_wave_info);
+  }
+
+  return klass;
+}
+
+const gchar * g_module_check_init (void);
+
+const gchar * g_module_check_init (void)
+{
+  gfs_init_stokes_wave_class ();
+  return NULL;
+}
diff --git a/modules/terrain.mod b/modules/terrain.mod
new file mode 100644
index 0000000..4f6798a
--- /dev/null
+++ b/modules/terrain.mod
@@ -0,0 +1,1674 @@
+/* Gerris - The GNU Flow Solver                       (-*-C-*-)
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <glob.h>
+#if GSL
+# include <gsl/gsl_linalg.h>
+#endif
+#include "refine.h"
+#include "solid.h"
+#include "rsurface.h"
+#include "river.h"
+
+static gchar * default_path = ".";
+
+/* RSurfaces */
+
+typedef struct {
+  RSurface ** rs;
+  guint nrs; 
+  gchar * path, * basename;  
+} RSurfaces;
+
+static void rsurfaces_destroy (RSurfaces * rs)
+{
+  g_free (rs->path);
+  g_free (rs->basename);
+  if (rs->rs) {
+    guint i;
+    for (i = 0; i < rs->nrs; i++)
+      r_surface_close (rs->rs[i]);
+    g_free (rs->rs);
+  }
+}
+
+static void rsurfaces_read (RSurfaces * rs, GtsFile * fp)
+{
+  gchar * path = NULL;
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_STRING, "basename", TRUE},
+      {GTS_STRING, "path",      TRUE},
+      {GTS_NONE}
+    };
+    var[0].data = &rs->basename;
+    var[1].data = &rs->path;
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+    path = g_strconcat (default_path, ":", rs->path, NULL);
+  }
+  else
+    path = g_strdup (default_path);
+
+  if (!strcmp (rs->basename, "*")) { /* file globbing */
+    gchar * pattern = g_strconcat (path, "/*.Data", NULL);
+    glob_t pglob;
+    if (glob (pattern, GLOB_ERR, NULL, &pglob)) {
+      gts_file_error (fp, "cannot find/open terrain databases in path:\n%s", pattern);
+      g_free (pattern);
+      g_free (path);
+      return;
+    }
+    g_free (pattern);
+    guint i;
+    for (i = 0; i < pglob.gl_pathc; i++) {
+      pglob.gl_pathv[i][strlen (pglob.gl_pathv[i]) - 5] = '\0';
+      rs->rs = g_realloc (rs->rs, (rs->nrs + 1)*sizeof (RSurface *));
+      rs->rs[rs->nrs] = r_surface_open (pglob.gl_pathv[i], "r", -1);
+      if (!rs->rs[rs->nrs]) {
+	gts_file_error (fp, "cannot open terrain database `%s'", pglob.gl_pathv[i]);
+	globfree (&pglob);
+	g_free (path);
+	return;
+      }
+      rs->nrs++;
+    }
+    globfree (&pglob);
+  }
+  else { /* basename is of the form: set1,set2,set3... */
+    gchar ** names = g_strsplit (rs->basename, ",", 0);
+    gchar ** s = names;
+    while (*s) {
+      rs->rs = g_realloc (rs->rs, (rs->nrs + 1)*sizeof (RSurface *));
+      if (path) {
+	/* search path */
+	gchar ** pathes = g_strsplit (path, ":", 0);
+	gchar ** spath = pathes, * fname;
+	g_assert (*spath);
+	do {
+	  fname = (*s)[0] == '/' ? g_strdup (*s) : g_strconcat (*spath, "/", *s, NULL);
+	  rs->rs[rs->nrs] = r_surface_open (fname, "r", -1);
+	} while (rs->rs[rs->nrs] == NULL && *(++spath));
+	g_strfreev (pathes);
+      }
+      else
+	rs->rs[rs->nrs] = r_surface_open (*s, "r", -1);
+      if (!rs->rs[rs->nrs]) {
+	if (path)
+	  gts_file_error (fp, "cannot find/open terrain database `%s' in path:\n%s", *s, path);
+	else
+	  gts_file_error (fp, "cannot open terrain database `%s'", *s);
+	g_strfreev (names);
+	g_free (path);
+	return;
+      }
+      rs->nrs++;
+      s++;
+    }
+    g_strfreev (names);
+  }
+  g_free (path);
+}
+
+static void rsurfaces_write (RSurfaces * rs, FILE * fp)
+{
+  if (rs->path || rs->basename) {
+    fputs (" {\n", fp);
+    if (rs->path)
+      fprintf (fp, "  path = %s\n", rs->path);
+    if (rs->basename)
+      fprintf (fp, "  basename = %s\n", rs->basename);
+    fputc ('}', fp);
+  }
+}
+
+/* GfsRefineTerrain: Header */
+
+typedef struct _GfsRefineTerrain         GfsRefineTerrain;
+
+#define NM 4
+
+struct _GfsRefineTerrain {
+  /*< private >*/
+  GfsRefine parent;
+  guint level;
+  gboolean refined;
+  GfsVariable * type;
+
+#if !FTT_2D
+  GfsVariable * min, * max;
+  gdouble front, scale;
+#endif
+
+  RSurfaces rs;
+
+  /*< public >*/
+  gchar * name;
+  GfsVariable * h[NM], * he, * hn, * hdmin, * hdmax;
+  GfsFunction * criterion;
+};
+
+#define GFS_REFINE_TERRAIN(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsRefineTerrain,\
+					           gfs_refine_terrain_class ())
+#define GFS_IS_REFINE_TERRAIN(obj)         (gts_object_is_from_class (obj,\
+						   gfs_refine_terrain_class ()))
+     
+GfsRefineClass * gfs_refine_terrain_class  (void);
+
+/* GfsRefineTerrain: Object */
+
+typedef struct {
+  FttVector c;
+  FttVector p[4];
+  gdouble min[2], max[2], h;
+  RSurfaces * rs;
+  FttCell * cell;
+} Polygon;
+
+static void map_inverse (GfsSimulation * sim, FttVector * p, Polygon * poly)
+{
+  gfs_simulation_map_inverse (sim, p);
+  if (p->x < poly->min[0]) poly->min[0] = p->x;
+  if (p->x > poly->max[0]) poly->max[0] = p->x;
+  if (p->y < poly->min[1]) poly->min[1] = p->y;
+  if (p->y > poly->max[1]) poly->max[1] = p->y;
+  poly->c.x += p->x; poly->c.y += p->y;
+}
+
+static void polygon_init (GfsSimulation * sim, Polygon * p, FttCell * cell, RSurfaces * rs)
+{
+  FttVector q;
+  ftt_cell_pos (cell, &q);
+  p->cell = cell;
+  p->rs = rs;
+  p->min[0] = p->min[1] = G_MAXDOUBLE;
+  p->max[0] = p->max[1] = - G_MAXDOUBLE;
+  p->c.x = p->c.y = 0.;
+  p->h = ftt_cell_size (cell)/2.;
+  p->p[0].x = q.x + p->h; p->p[0].y = q.y + p->h;
+  map_inverse (sim, &p->p[0], p);
+  p->p[1].x = q.x - p->h; p->p[1].y = q.y + p->h;
+  map_inverse (sim, &p->p[1], p);
+  p->p[2].x = q.x - p->h; p->p[2].y = q.y - p->h;
+  map_inverse (sim, &p->p[2], p);
+  p->p[3].x = q.x + p->h; p->p[3].y = q.y - p->h;
+  map_inverse (sim, &p->p[3], p);
+  p->c.x /= 4; p->c.y /= 4;
+  p->h = MAX (p->max[0] - p->min[0], p->max[1] - p->min[1])/2.;
+}
+
+static gboolean right (const double a[2], const double b[2], const double c[2])
+{
+  return (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0]) < 0.;
+}
+
+static gboolean polygon_contains (Polygon * p, gdouble q[2])
+{
+  if (right (&p->p[0].x, &p->p[1].x, q))
+    return FALSE;
+  if (right (&p->p[1].x, &p->p[2].x, q))
+    return FALSE;
+  if (right (&p->p[2].x, &p->p[3].x, q))
+    return FALSE;
+  if (right (&p->p[3].x, &p->p[0].x, q))
+    return FALSE;
+  return TRUE;
+}
+
+static gboolean polygon_includes (RSurfaceRect rect, Polygon * p)
+{
+  gdouble q[2];
+  q[0] = rect[0].l; q[1] = rect[1].l;
+  if (!polygon_contains (p, q))
+    return FALSE;
+  q[0] = rect[0].l; q[1] = rect[1].h;
+  if (!polygon_contains (p, q))
+    return FALSE;
+  q[0] = rect[0].h; q[1] = rect[1].l;
+  if (!polygon_contains (p, q))
+    return FALSE;
+  q[0] = rect[0].h; q[1] = rect[1].h;
+  if (!polygon_contains (p, q))
+    return FALSE;
+  return TRUE;
+}
+
+static gboolean polygon_intersects (RSurfaceRect rect, Polygon * p)
+{
+  /* fixme: this could be improved? */
+  return (rect[0].l <= p->max[0] && rect[0].h >= p->min[0] &&
+	  rect[1].l <= p->max[1] && rect[1].h >= p->min[1]);
+}
+
+typedef struct {
+  gdouble H[NM+1], m[NM][NM];
+  gdouble h[NM], he, cond, min, max;
+  GfsRefineTerrain * t;
+  FttCell * cell;
+  gboolean relative;
+} RMS;
+
+static void rms_init (GfsRefineTerrain * t, RMS * rms, Polygon * p, gboolean relative)
+{
+  guint i, j;
+  for (i = 0; i < NM + 1; i++)
+    rms->H[i] = 0.;
+  for (i = 0; i < NM; i++)
+    for (j = 0; j < NM; j++)
+      rms->m[i][j] = 0.;
+  rms->t = t;
+  rms->cell = p->cell;
+  rms->relative = relative;
+  rms->min = G_MAXDOUBLE;
+  rms->max = - G_MAXDOUBLE;
+}
+
+static void function_from_corners (gdouble h[4], gdouble H[4])
+{
+  h[0] = (H[0] + H[1] + H[2] + H[3])/4.;
+  h[1] = (H[0] - H[1] - H[2] + H[3])/4.;
+  h[2] = (H[0] + H[1] - H[2] - H[3])/4.;
+  h[3] = (H[0] - H[1] + H[2] - H[3])/4.;  
+}
+
+static gdouble rms_minimum (RMS * rms)
+{
+  if (rms->m[0][0] == 0.)
+    return 0.;
+  return sqrt (fabs (rms->h[0]*(rms->h[0]*rms->m[0][0] + 
+				2.*(rms->h[1]*rms->m[0][1] + 
+				    rms->h[2]*rms->m[0][2] +
+				    rms->h[3]*rms->m[0][3] - rms->H[0])) +
+		     rms->h[1]*(rms->h[1]*rms->m[1][1] + 
+				2.*(rms->h[2]*rms->m[1][2] +
+				    rms->h[3]*rms->m[1][3] - rms->H[1])) +
+		     rms->h[2]*(rms->h[2]*rms->m[2][2] +
+				2.*(rms->h[3]*rms->m[2][3] - rms->H[2])) +
+		     rms->h[3]*(rms->h[3]*rms->m[3][3] - 2.*rms->H[3]) +
+		     rms->H[4])/rms->m[0][0]);
+}
+
+static gdouble cell_value (FttCell * cell, GfsVariable * h[NM], FttVector p)
+{
+  gdouble size = ftt_cell_size (cell)/2.;
+  FttVector q;
+  ftt_cell_pos (cell, &q);
+  p.x = (p.x - q.x)/size;
+  p.y = (p.y - q.y)/size;
+  return (GFS_VALUE (cell, h[0]) + 
+	  GFS_VALUE (cell, h[1])*p.x + 
+	  GFS_VALUE (cell, h[2])*p.y + 
+	  GFS_VALUE (cell, h[3])*p.x*p.y);
+}
+
+static void corners_from_parent (FttCell * cell, GfsRefineTerrain * t, gdouble H[4])
+{
+  gdouble size = ftt_cell_size (cell);
+  FttCell * parent = ftt_cell_parent (cell);
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  p.x += size/2.; p.y += size/2.;
+  H[0] = cell_value (parent, t->h, p);
+  p.x -= size;
+  H[1] = cell_value (parent, t->h, p);
+  p.y -= size;
+  H[2] = cell_value (parent, t->h, p);
+  p.x += size;
+  H[3] = cell_value (parent, t->h, p);
+}
+
+static void variance_check (RMS * rms)
+{
+  g_assert (rms->m[0][0] >= NM);
+  gdouble H[4], h[4];
+  guint i;
+  h[0] = rms->h[0] + rms->h[1] + rms->h[2] + rms->h[3];
+  h[1] = rms->h[0] - rms->h[1] + rms->h[2] - rms->h[3];
+  h[2] = rms->h[0] - rms->h[1] - rms->h[2] + rms->h[3];
+  h[3] = rms->h[0] + rms->h[1] - rms->h[2] - rms->h[3];
+  if (rms->relative) {
+    gdouble H0[4];
+    corners_from_parent (rms->cell, rms->t, H0);
+    for (i = 0; i < 4; i++)
+      H[i] = CLAMP (h[i], rms->min - H0[i], rms->max - H0[i]);
+  }
+  else
+    for (i = 0; i < 4; i++)
+      H[i] = CLAMP (h[i], rms->min, rms->max);
+  function_from_corners (rms->h, H);
+}
+
+static void rms_update (RMS * rms)
+{
+  guint i;
+  if (rms->m[0][0] == 0.) {
+    for (i = 1; i < NM; i++)
+      rms->h[i] = 0.;
+    rms->h[0] = G_MAXDOUBLE;
+    rms->he = 0.;
+    rms->cond = G_MAXDOUBLE;
+    return;
+  }
+  else if (rms->m[0][0] >= NM) {
+    guint j;
+    for (i = 1; i < NM; i++)
+      for (j = 0; j < i; j++)
+	rms->m[i][j] = rms->m[j][i];
+#if GSL  
+    double m[NM*NM], v[NM*NM], s[NM];
+    gsl_matrix_view gv = gsl_matrix_view_array (v, NM, NM);
+    gsl_vector_view gs = gsl_vector_view_array (s, NM);
+    for (i = 0; i < NM; i++)
+      for (j = 0; j < NM; j++)
+	m[i+NM*j] = rms->m[i][j];
+    gsl_matrix_view gm = gsl_matrix_view_array (m, NM, NM);
+    gsl_linalg_SV_decomp_jacobi (&gm.matrix, &gv.matrix, &gs.vector);
+    rms->cond = s[NM - 1] > 0. ? s[0]/s[NM - 1] : G_MAXDOUBLE;
+    if (rms->cond < 10000.) {
+      gsl_vector_view gH = gsl_vector_view_array (rms->H, NM);
+      gsl_vector_view gh = gsl_vector_view_array (rms->h, NM);
+      gsl_linalg_SV_solve (&gm.matrix, &gv.matrix, &gs.vector, &gH.vector, &gh.vector);
+      variance_check (rms);
+      rms->he = rms_minimum (rms);
+      return;
+    }
+#else
+    gdouble ** m = gfs_matrix_new (NM, NM, sizeof (gdouble));
+    for (i = 0; i < NM; i++)
+      for (j = 0; j < NM; j++)
+	m[i][j] = rms->m[i][j];
+    if (gfs_matrix_inverse (m, NM, 1e-5)) {
+      for (i = 0; i < NM; i++) {
+	rms->h[i] = 0.;
+	for (j = 0; j < NM; j++)
+	  rms->h[i] += m[i][j]*rms->H[j];
+      }
+      gfs_matrix_free (m);
+      variance_check (rms);
+      rms->he = rms_minimum (rms);
+      return;
+    }
+    gfs_matrix_free (m);
+#endif
+  }
+  rms->h[0] = rms->H[0]/rms->m[0][0];
+  for (i = 1; i < NM; i++)
+    rms->h[i] = 0.;
+  rms->he = rms_minimum (rms);
+}
+
+#if DEBUG
+static gdouble rms_value (RMS * rms, FttVector * p)
+{
+  return rms->h[0] + rms->h[1]*p->x + rms->h[2]*p->y + rms->h[3]*p->x*p->y;
+}
+
+static void rms_write (RMS * rms, Polygon * p)
+{
+  FttVector q, r;
+  q.x = p->c.x + p->h; q.y = p->c.y + p->h;
+  r.x = 1.; r.y = 1.;
+  fprintf (stderr, "%g %g %g\n", q.x, q.y, rms_value (rms, &r)/20000.);
+  q.x = p->c.x + p->h; q.y = p->c.y - p->h;
+  r.x = 1.; r.y = - 1.;
+  fprintf (stderr, "%g %g %g\n", q.x, q.y, rms_value (rms, &r)/20000.);
+  q.x = p->c.x - p->h; q.y = p->c.y - p->h;
+  r.x = - 1.; r.y = - 1.;
+  fprintf (stderr, "%g %g %g\n", q.x, q.y, rms_value (rms, &r)/20000.);
+  q.x = p->c.x - p->h; q.y = p->c.y + p->h;
+  r.x = - 1.; r.y = 1.;
+  fprintf (stderr, "%g %g %g\n", q.x, q.y, rms_value (rms, &r)/20000.);
+}
+
+static int write_points (double p[3], Polygon * poly)
+{
+  if (polygon_contains (poly, p))
+    fprintf (stderr, "aa %g %g %g\n", p[0], p[1], p[2]);
+}
+#endif
+
+#define RAW        0. /* fitted but not continuous (C0) */
+#define FAIR       1. /* fitted and C0 */
+#define REFINED    2. /* non-fitted refined cell */
+#define NEW_CHILD  3. /* non-fitted child extrapolated from its parent */
+#define CONTAINS_SURFACE 4. /* 3D-only */
+#define BOUNDARY 5.         /* 3D-only */
+
+static void parent_cell_coefficients (FttCell * cell, GfsVariable ** v, gdouble hP[NM])
+{
+  FttCell * parent = ftt_cell_parent (cell);
+  gdouble h[4];
+  guint i;
+  for (i = 0; i < 4; i++)
+    h[i] = GFS_VALUE (parent, v[i]);
+
+  FttVector p;
+  ftt_cell_relative_pos (cell, &p);
+  p.x *= 2.; p.y *= 2.;
+
+  hP[0] = h[0] +  h[1]*p.x + (h[2] + h[3]*p.x)*p.y;
+  hP[1] = (h[1] + h[3]*p.y)/2.;
+  hP[2] = (h[2] + h[3]*p.x)/2.;
+  hP[3] = h[3]/4.;
+}
+
+static void projection_matrix (Polygon * poly, double m[2][2])
+{
+  double x[4], y[4];
+  guint i;
+  for (i = 0; i < 4; i++) {
+    x[i] = (poly->p[i].x - poly->c.x)/poly->h;
+    y[i] = (poly->p[i].y - poly->c.y)/poly->h;
+  }
+  m[0][0] = (x[0] - x[1] + x[3] - x[2])/4.;
+  m[0][1] = (x[0] + x[1] - x[3] - x[2])/4.;
+  m[1][0] = (y[0] - y[1] + y[3] - y[2])/4.;
+  m[1][1] = (y[0] + y[1] - y[3] - y[2])/4.;
+}
+
+static void update_terrain_rms (GfsRefineTerrain * t, Polygon * poly, gboolean relative, RMS * rms)
+{
+  rms_init (t, rms, poly, relative);
+  RSurfaceSum s;
+  r_surface_sum_init (&s);
+  guint i;
+  RSurfaceRect rect;
+  rect[0].l = poly->c.x - poly->h/2.; rect[0].h = poly->c.x + poly->h/2.; 
+  rect[1].l = poly->c.y - poly->h/2.; rect[1].h = poly->c.y + poly->h/2.; 
+  for (i = 0; i < poly->rs->nrs; i++)
+    r_surface_query_region_sum (poly->rs->rs[i],
+				(RSurfaceCheck) polygon_includes,
+				(RSurfaceCheck) polygon_intersects, poly, 
+				rect, &s);
+
+  rms->m[0][0] = s.n;
+  if (s.n > 0) {
+    RSurfaceSum sp;
+
+    sp.n = s.n;
+    sp.H0 = s.H0;
+    sp.H4 = s.H4;
+    sp.Hmin = s.Hmin;
+    sp.Hmax = s.Hmax;
+
+    /* The sums returned by r_surface_query_region_sum are defined in
+       a (lon,lat) coordinate system, we need to project these into
+       the local Cartesian coordinate system. The corresponding
+       transform is given by matrix p below. */
+    double p[2][2];
+    projection_matrix (poly, p);
+
+    /* This is the transformation of the sums */
+    double det = p[0][0]*p[1][1] - p[0][1]*p[1][0], det1 = det;
+    g_assert (det > 0.1);
+
+    sp.m01 = (s.m01*p[1][1] - s.m02*p[0][1])/det;
+    sp.m02 = (s.m02*p[0][0] - s.m01*p[1][0])/det;
+    sp.H1 =  (s.H1*p[1][1] - s.H2*p[0][1])/det;
+    sp.H2 =  (s.H2*p[0][0] - s.H1*p[1][0])/det;
+
+    det *= det1;
+    sp.m11 = (p[1][1]*p[1][1]*s.m11 + p[0][1]*p[0][1]*s.m22 - 2.*p[0][1]*p[1][1]*s.m03)/det;
+    sp.m22 = (p[1][0]*p[1][0]*s.m11 + p[0][0]*p[0][0]*s.m22 - 2.*p[0][0]*p[1][0]*s.m03)/det;
+    sp.m03 = - (p[1][0]*p[1][1]*s.m11 + p[0][0]*p[0][1]*s.m22 
+		- (p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.m03)/det;
+    sp.H3  = - (p[1][0]*p[1][1]*s.H5 + p[0][0]*p[0][1]*s.H6 
+		- (p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.H3)/det;
+
+    det *= det1;
+    sp.m13 = (- p[1][0]*p[1][1]*p[1][1]*s.m44 
+	      + p[0][0]*p[0][1]*p[0][1]*s.m55
+	      + p[1][1]*(p[0][0]*p[1][1] + 2.*p[0][1]*p[1][0])*s.m13
+	      - p[0][1]*(2.*p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.m23)/det;
+    sp.m23 = (+ p[1][0]*p[1][0]*p[1][1]*s.m44 
+	      - p[0][0]*p[0][0]*p[0][1]*s.m55
+	      - p[1][0]*(2.*p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.m13
+	      + p[0][0]*(p[0][0]*p[1][1] + 2.*p[0][1]*p[1][0])*s.m23)/det;
+
+    det *= det1;
+    sp.m33 = (+ p[1][0]*p[1][0]*p[1][1]*p[1][1]*s.m66
+	      + p[0][0]*p[0][0]*p[0][1]*p[0][1]*s.m77
+	      - 2.*p[1][0]*p[1][1]*(p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.m67 
+	      - 2.*p[0][0]*p[0][1]*(p[0][0]*p[1][1] + p[0][1]*p[1][0])*s.m76
+	      + (p[0][0]*p[0][0]*p[1][1]*p[1][1]
+		 + 4.*p[0][0]*p[0][1]*p[1][0]*p[1][1]
+		 + p[0][1]*p[0][1]*p[1][0]*p[1][0])*s.m33)/det;
+
+    rms->m[0][1] = sp.m01;
+    rms->m[0][2] = sp.m02;
+    rms->m[1][1] = sp.m11;
+    rms->m[2][2] = sp.m22;
+    rms->m[0][3] = sp.m03;
+    rms->m[1][3] = sp.m13;
+    rms->m[2][3] = sp.m23;
+    rms->m[3][3] = sp.m33;
+    rms->m[1][2] = rms->m[0][3];
+
+    if (rms->relative) {
+      double hp[NM];
+
+      parent_cell_coefficients (rms->cell, rms->t->h, hp);
+      rms->H[0] = sp.H0 - sp.n*hp[0] - sp.m01*hp[1] - sp.m02*hp[2] - sp.m03*hp[3];
+
+      /* See terrain.mac for a "maxima" derivation of the terms below */
+      rms->H[1] = sp.H1 - hp[0]*sp.m01 - hp[1]*sp.m11 - hp[2]*sp.m03 - hp[3]*sp.m13;
+      rms->H[2] = sp.H2 - hp[0]*sp.m02 - hp[1]*sp.m03 - hp[2]*sp.m22 - hp[3]*sp.m23;
+      rms->H[3] = sp.H3 - hp[0]*sp.m03 - hp[1]*sp.m13 - hp[2]*sp.m23 - hp[3]*sp.m33;
+      rms->H[4] = (sp.H4 - 2.*hp[3]*sp.H3 - 2.*hp[2]*sp.H2 - 2.*hp[1]*sp.H1 - 2.*hp[0]*sp.H0
+		   + hp[3]*hp[3]*sp.m33
+		   + 2.*hp[2]*hp[3]*sp.m23
+		   + hp[2]*hp[2]*sp.m22
+		   + 2.*hp[1]*hp[3]*sp.m13
+		   + hp[1]*hp[1]*sp.m11
+		   + 2.*(hp[0]*hp[3] + hp[1]*hp[2])*sp.m03
+		   + 2.*hp[0]*hp[2]*sp.m02
+		   + 2.*hp[0]*hp[1]*sp.m01
+		   + hp[0]*hp[0]*sp.n);
+    }
+    else {
+      rms->H[0] = sp.H0;
+      rms->H[1] = sp.H1;
+      rms->H[2] = sp.H2;
+      rms->H[3] = sp.H3;
+      rms->H[4] = sp.H4;
+    }
+    rms->max = sp.Hmax;
+    rms->min = sp.Hmin;
+  }
+}
+
+static void update_terrain (FttCell * cell, GfsRefineTerrain * t)
+{
+  RMS rms;
+  guint i;
+  g_assert (GFS_VALUE (cell, t->type) == REFINED);
+  Polygon poly;
+  polygon_init (gfs_object_simulation (t), &poly, cell, &t->rs);
+  update_terrain_rms (t, &poly, ftt_cell_parent (cell) != NULL, &rms);
+  rms_update (&rms);
+
+  for (i = 0; i < NM; i++)
+    GFS_VALUE (cell, t->h[i]) = rms.h[i];
+  GFS_VALUE (cell, t->he) = rms.he;
+  GFS_VALUE (cell, t->hn) = rms.m[0][0];
+  GFS_VALUE (cell, t->hdmin) = rms.min;
+  GFS_VALUE (cell, t->hdmax) = rms.max;
+  GFS_VALUE (cell, t->type) = RAW;
+}
+
+static void function_from_parent (FttCell * cell, GfsRefineTerrain * t, gdouble h[4])
+{
+  gdouble H[4];
+  corners_from_parent (cell, t, H);
+  function_from_corners (h, H);
+}
+
+static void cell_fine_init (FttCell * parent, GfsRefineTerrain * t)
+{
+  gfs_cell_fine_init (parent, GFS_DOMAIN (gfs_object_simulation (t)));
+  FttCellChildren child;
+  ftt_cell_children (parent, &child);
+  guint i;
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      gdouble h[NM];
+      function_from_parent (child.c[i], t, h);
+      guint j;
+      for (j = 0; j < NM; j++)
+	GFS_VALUE (child.c[i], t->h[j]) = h[j];
+      GFS_VALUE (child.c[i], t->he) = GFS_VALUE (parent, t->he);
+      GFS_VALUE (child.c[i], t->hn) = GFS_VALUE (parent, t->hn)/FTT_CELLS;
+      GFS_VALUE (child.c[i], t->hdmin) = GFS_VALUE (parent, t->hdmin);
+      GFS_VALUE (child.c[i], t->hdmax) = GFS_VALUE (parent, t->hdmax);
+      GFS_VALUE (child.c[i], t->type) = NEW_CHILD;
+    }
+}
+
+static gdouble corner_value (GfsRefineTerrain * t, FttVector * p, gdouble eps, guint level)
+{
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (t));
+  gdouble v = 0., w = 0.;
+  gint i, j;
+  for (i = -1; i <= 1; i += 2)
+    for (j = -1; j <= 1; j += 2) {
+      FttVector q;
+      q.x = p->x + eps*i; q.y = p->y + eps*j; q.z = p->z;
+      FttCell * cell = gfs_domain_locate (domain, q, level, NULL);
+      if (cell) {
+	if (ftt_cell_level (cell) < level)
+	    return 0.;
+	else if (GFS_VALUE (cell, t->type) == FAIR)
+	  return cell_value (cell, t->h, *p);
+	gdouble n = GFS_VALUE (cell, t->hn);
+	if (n > 0.) {
+	  g_assert (GFS_VALUE (cell, t->type) == RAW);
+	  v += cell_value (cell, t->h, *p);
+	  w += 1.;
+	}
+      }
+    }
+  return w > 0 ? v/w : 0.;
+}
+
+static void update_error_estimate (FttCell * cell, GfsRefineTerrain * t, gboolean relative)
+{
+  if (GFS_VALUE (cell, t->hn) > 0.) {
+    RMS rms;
+    guint i;
+    Polygon poly;
+    polygon_init (gfs_object_simulation (t), &poly, cell, &t->rs);
+    update_terrain_rms (t, &poly, relative, &rms);
+    for (i = 0; i < NM; i++)
+      rms.h[i] = GFS_VALUE (cell, t->h[i]);
+    GFS_VALUE (cell, t->he) = rms_minimum (&rms);
+  }
+  else
+    GFS_VALUE (cell, t->he) = 0.;
+}
+
+static void remove_knots (FttCell * cell, GfsRefineTerrain * t)
+{
+  gdouble size = ftt_cell_size (cell), eps = size/1000.;
+  guint level = ftt_cell_level (cell);
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  gdouble h[4], H[4];
+  p.x += size/2.; p.y += size/2.;
+  H[0] = corner_value (t, &p, eps, level);
+  p.x -= size;
+  H[1] = corner_value (t, &p, eps, level);
+  p.y -= size;
+  H[2] = corner_value (t, &p, eps, level);
+  p.x += size;
+  H[3] = corner_value (t, &p, eps, level);
+  function_from_corners (h, H);
+  guint i;
+  for (i = 0; i < NM; i++)
+    GFS_VALUE (cell, t->h[i]) = h[i];
+  GFS_VALUE (cell, t->type) = FAIR;
+
+  update_error_estimate (cell, t, ftt_cell_parent (cell) != NULL);
+}
+
+static void update_height_and_check_for_refinement (FttCell * cell, GfsRefineTerrain * t)
+{
+  if (GFS_VALUE (cell, t->type) == FAIR) {
+    if (ftt_cell_parent (cell)) {
+      gdouble h[4];
+      function_from_parent (cell, t, h);
+      guint i;
+      for (i = 0; i < NM; i++)
+	GFS_VALUE (cell, t->h[i]) += h[i];
+    }
+
+    if (ftt_cell_level (cell) < gfs_function_value (GFS_REFINE (t)->maxlevel, cell) &&
+	gfs_function_value (t->criterion, cell)) {
+      g_assert (FTT_CELL_IS_LEAF (cell));
+      ftt_cell_refine_single (cell, (FttCellInitFunc) cell_fine_init, t);
+      FttCellChildren child;
+      guint i;
+      ftt_cell_children (cell, &child);
+      for (i = 0; i < FTT_CELLS; i++)
+	GFS_VALUE (child.c[i], t->type) = REFINED;
+    }
+
+    if (!FTT_CELL_IS_LEAF (cell))
+      t->refined = TRUE;
+  }
+  else
+    g_assert (GFS_VALUE (cell, t->type) == NEW_CHILD);
+}
+
+static void reset_terrain (FttCell * cell, GfsRefineTerrain * t)
+{
+  guint i;
+  for (i = 0; i < NM; i++)
+    GFS_VALUE (cell, t->h[i]) = 0.;
+  GFS_VALUE (cell, t->type) = REFINED;
+  if (FTT_CELL_IS_LEAF (cell) && ftt_cell_level (cell) < t->level)
+    t->level = ftt_cell_level (cell);
+}
+
+#if FTT_2D
+# define traverse_boundary(domain,order,flags,depth,func,data) \
+         gfs_domain_cell_traverse(domain,order,flags,depth,func,data)
+#else /* 3D */
+# define traverse_boundary(domain,order,flags,depth,func,data) \
+         gfs_domain_cell_traverse_boundary(domain,FTT_FRONT,order,flags,depth,func,data)
+
+static void terrain_min_max (gdouble H[NM], gdouble minmax[2], gdouble scale)
+{
+  gdouble dx, dy;
+  minmax[0] = G_MAXDOUBLE; minmax[1] = - G_MAXDOUBLE;
+  for (dx = -1.; dx <= 1.; dx += 2.)
+    for (dy = -1.; dy <= 1.; dy += 2.) {
+      gdouble v = H[0] + dx*H[1] + dy*H[2] + dx*dy*H[3];
+      if (v < minmax[0]) minmax[0] = v;
+      if (v > minmax[1]) minmax[1] = v;
+    }
+  minmax[0] *= scale;
+  minmax[1] *= scale;
+}
+
+static void min_max (FttCell * cell, GfsRefineTerrain * t)
+{
+  gdouble minmax[2] = { G_MAXDOUBLE, - G_MAXDOUBLE };
+  if (FTT_CELL_IS_LEAF (cell)) {
+    gdouble h[4];
+    h[0] = GFS_VALUE (cell, t->h[0]);
+    h[1] = GFS_VALUE (cell, t->h[1]);
+    h[2] = GFS_VALUE (cell, t->h[2]);
+    h[3] = GFS_VALUE (cell, t->h[3]);
+    terrain_min_max (h, minmax, t->scale);
+
+    FttVector p;
+    ftt_cell_pos (cell, &p);
+    if (p.z > t->front)
+      t->front = p.z;
+  }
+  else {
+    FttCellChildren child;
+    guint i;
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i]) {
+	if (GFS_VALUE (child.c[i], t->max) > minmax[1])
+	  minmax[1] = GFS_VALUE (child.c[i], t->max);
+	if (GFS_VALUE (child.c[i], t->min) < minmax[0])
+	  minmax[0] = GFS_VALUE (child.c[i], t->min);	
+      }
+  }
+  GFS_VALUE (cell, t->min) = minmax[0];
+  GFS_VALUE (cell, t->max) = minmax[1];
+  GFS_VALUE (cell, t->type) = BOUNDARY;
+}
+
+static gboolean refine_terrain_from_boundary (FttCell * cell, GfsRefineTerrain * t)
+{
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  gdouble h = ftt_cell_size (cell)/2., zmin = p.z - h, zmax = p.z + h;
+  p.z = t->front;
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (t));
+  FttCell * boundary = gfs_domain_locate (domain, p, ftt_cell_level (cell), NULL);
+  g_assert (boundary);
+  if (GFS_VALUE (boundary, t->min) > zmax || GFS_VALUE (boundary, t->max) < zmin)
+    return FALSE;
+  GFS_VALUE (cell, t->type) = CONTAINS_SURFACE;
+  return !FTT_CELL_IS_LEAF (boundary);
+}
+
+static void refine_box (GfsBox * box, GfsRefineTerrain * t)
+{
+  ftt_cell_refine (box->root, 
+		   (FttCellRefineFunc) refine_terrain_from_boundary, t,
+		   (FttCellInitFunc) gfs_cell_fine_init, gfs_box_domain (box));
+}
+
+static void init_terrain_from_boundary (FttCell * cell, GfsRefineTerrain * t)
+{
+  if (GFS_VALUE (cell, t->type) == CONTAINS_SURFACE) {
+    FttVector p;
+    ftt_cell_pos (cell, &p);
+    p.z = t->front;
+    GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (t));
+    FttCell * boundary = gfs_domain_locate (domain, p, -1, NULL);
+    g_assert (boundary);
+    g_assert (ftt_cell_level (cell) == ftt_cell_level (boundary));
+    guint i;
+    for (i = 0; i < NM; i++)
+      GFS_VALUE (cell, t->h[i]) = GFS_VALUE (boundary, t->h[i]);
+    GFS_VALUE (cell, t->he) = GFS_VALUE (boundary, t->he);
+    GFS_VALUE (cell, t->hn) = GFS_VALUE (boundary, t->hn);
+  }
+}
+
+static gboolean coarsen_boundary (FttCell * cell, GfsRefineTerrain * t)
+{
+  return (GFS_VALUE (cell, t->type) != CONTAINS_SURFACE);
+}
+
+static void coarsen_box (GfsBox * box, GfsRefineTerrain * t)
+{
+  ftt_cell_coarsen (box->root,
+		    (FttCellCoarsenFunc) coarsen_boundary, t,
+		    (FttCellCleanupFunc) gfs_cell_cleanup, gfs_box_domain (box));
+}
+
+static void reset_empty_cell (FttCell * cell, GfsRefineTerrain * t)
+{
+  if (GFS_VALUE (cell, t->type) != CONTAINS_SURFACE) {
+    guint i;
+    for (i = 0; i < NM; i++)
+      GFS_VALUE (cell, t->h[i]) = G_MAXDOUBLE;
+    GFS_VALUE (cell, t->he) = G_MAXDOUBLE;
+    GFS_VALUE (cell, t->hn) = G_MAXDOUBLE;
+  }
+}
+#endif /* 3D */
+
+#if DEBUG
+static void draw_terrain (FttCell * cell, gpointer * data)
+{
+  GfsRefineTerrain * t = data[0];
+  FILE * fp = data[1];
+  gdouble h = ftt_cell_size (cell);
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  p.x += h/2.; p.y += h/2.;
+  fprintf (fp, "%g %g %g\n", p.x, p.y, cell_value (cell, t->h, p));
+  p.x -= h;
+  fprintf (fp, "%g %g %g\n", p.x, p.y, cell_value (cell, t->h, p));
+  p.y -= h;
+  fprintf (fp, "%g %g %g\n", p.x, p.y, cell_value (cell, t->h, p));
+  p.x += h;
+  fprintf (fp, "%g %g %g\n", p.x, p.y, cell_value (cell, t->h, p));
+}
+
+static void draw_level (GfsDomain * domain, GfsRefine * refine, guint level, const gchar * name)
+{
+  gpointer data[2];
+  data[0] = refine;
+  data[1] = fopen (name, "w");
+  fprintf (data[1], "QUAD\n");
+  traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, level,
+		     (FttCellTraverseFunc) draw_terrain, data);
+  fclose (data[1]);
+}
+
+static void draw_all (GfsDomain * domain, GfsRefine * refine, const gchar * name)
+{
+  gpointer data[2];
+  data[0] = refine;
+  data[1] = fopen (name, "w");
+  //  fprintf (data[1], "QUAD\n");
+  traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		     (FttCellTraverseFunc) draw_terrain, data);
+  fclose (data[1]);
+}
+#endif
+
+#define ASCII_ZERO 48 /* ASCII value for character "0" */
+
+static void terrain_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  guint len = strlen (v->name) - 1;
+  gint c = v->name[len] - ASCII_ZERO;
+  guint n;
+  gdouble h[NM];
+
+  g_assert (c >= 0 && c < NM);
+  for (n = 0; n < NM; n++) {
+    GSList * i = v->domain->variables;
+    while (i && (!GFS_VARIABLE1 (i->data)->name || 
+		 strncmp (v->name, GFS_VARIABLE1 (i->data)->name, len) ||
+		 GFS_VARIABLE1 (i->data)->name[len] != ASCII_ZERO + n))
+      i = i->next;
+    g_assert (i);
+    h[n] = GFS_VALUE (parent, GFS_VARIABLE1 (i->data));
+  }
+
+  ftt_cell_children (parent, &child);
+  if (h[0] == G_MAXDOUBLE) {
+    for (n = 0; n < FTT_CELLS; n++)
+      if (child.c[n])
+	GFS_VALUE (child.c[n], v) = G_MAXDOUBLE;
+  }
+  else {
+    gdouble size = ftt_cell_size (parent)/4.;
+    for (n = 0; n < FTT_CELLS; n++)
+      if (child.c[n]) {
+	gdouble hc[NM];
+	FttVector p;
+	ftt_cell_relative_pos (child.c[n], &p);
+	p.x *= 2.; p.y *= 2.;
+	hc[0] = h[0] + h[1]*p.x + h[2]*p.y + h[3]*p.x*p.y;
+	hc[1] = (h[1] + h[3]*p.y)/2.;
+	hc[2] = (h[2] + h[3]*p.x)/2.;
+	hc[3] = h[3]/4.;
+#if !FTT_2D
+	ftt_cell_pos (child.c[n], &p);
+	gdouble zmin = p.z - size, zmax = p.z + size, minmax[2];
+	p.z = 1.;
+	gfs_simulation_map (GFS_SIMULATION (v->domain), &p);
+	terrain_min_max (hc, minmax, p.z);
+	if (minmax[0] > zmax || minmax[1] < zmin)
+	  GFS_VALUE (child.c[n], v) = G_MAXDOUBLE;
+	else
+#endif
+	  GFS_VALUE (child.c[n], v) = hc[c];
+      }
+  }
+}
+
+static void terrain_refine (GfsRefine * refine, GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsRefineTerrain * t = GFS_REFINE_TERRAIN (refine);
+  t->type = gfs_temporary_variable (domain);
+  t->level = G_MAXINT/2;
+  traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) reset_terrain, refine);
+  do {
+    traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, t->level,
+		       (FttCellTraverseFunc) update_terrain, refine);
+    traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, t->level,
+		       (FttCellTraverseFunc) remove_knots, refine);
+    t->refined = FALSE;
+    traverse_boundary (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, t->level,
+		       (FttCellTraverseFunc) update_height_and_check_for_refinement,
+		       refine);
+#if DEBUG
+    GfsNorm norm = gfs_domain_norm_variable (domain, t->he, NULL, FTT_TRAVERSE_LEAFS, -1);
+    fprintf (stderr, "level: %d bias: %g 1: %g 2: %g inf: %g\n", 
+	     t->level, norm.bias, norm.first, norm.second, norm.infty);
+    fprintf (stderr, "level: %d depth: %d\n", t->level, gfs_domain_depth (domain));
+    gchar name[] = "/tmp/level-x";
+    name[11] = ASCII_ZERO + t->level;
+    draw_level (domain, refine, t->level, name);
+#endif
+    t->level++;
+  } while (t->refined);
+#if DEBUG
+  draw_all (domain, refine, "/tmp/all");
+#endif
+#if !FTT_2D
+  /* The height field is only defined on the front boundary, we need
+     to define it volumetrically */
+  t->min = gfs_temporary_variable (domain);
+  t->max = gfs_temporary_variable (domain);
+  t->front = - G_MAXDOUBLE;
+  FttVector p = {0.,0.,1.};
+  gfs_simulation_map (sim, &p);
+  t->scale = p.z;
+  gfs_domain_cell_traverse_boundary (domain, FTT_FRONT, FTT_POST_ORDER, FTT_TRAVERSE_ALL, -1,
+				     (FttCellTraverseFunc) min_max, t);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) refine_box, t);
+  gts_object_destroy (GTS_OBJECT (t->min));
+  gts_object_destroy (GTS_OBJECT (t->max));
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) init_terrain_from_boundary, t);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) coarsen_box, t);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) reset_empty_cell, t);
+#endif /* 3D */  
+  gts_object_destroy (GTS_OBJECT (t->type));
+  guint i;
+  for (i = 0; i < NM; i++)
+    t->h[i]->coarse_fine = terrain_coarse_fine;
+}
+
+static void refine_terrain_destroy (GtsObject * object)
+{
+  GfsRefineTerrain * t = GFS_REFINE_TERRAIN (object);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (object));
+
+  if (t->name) {
+    gchar * dname = g_strconcat (t->name, "min", NULL);
+    gfs_domain_remove_derived_variable (domain, dname);
+    g_free (dname);
+    
+    dname = g_strconcat (t->name, "max", NULL);
+    gfs_domain_remove_derived_variable (domain, dname);
+    g_free (dname);
+  }
+  g_free (t->name);
+
+  rsurfaces_destroy (&t->rs);
+  
+  gts_object_destroy (GTS_OBJECT (t->criterion));  
+  (* GTS_OBJECT_CLASS (gfs_refine_terrain_class ())->parent_class->destroy) (object);
+}
+
+static gdouble terrain_hmin (FttCell * cell, FttCellFace * face, 
+			     GfsDomain * domain, GfsRefineTerrain * t)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  gdouble dx, dy, min = G_MAXDOUBLE;
+  gdouble H0 = GFS_VALUE (cell, t->h[0]), H1 = GFS_VALUE (cell, t->h[1]);
+  gdouble H2 = GFS_VALUE (cell, t->h[2]), H3 = GFS_VALUE (cell, t->h[3]);
+
+  for (dx = -1.; dx <= 1.; dx += 2.)
+    for (dy = -1.; dy <= 1.; dy += 2.) {
+      double v = H0 + dx*H1 + dy*H2 + dx*dy*H3;
+      if (v < min) min = v;
+    }
+  return min;
+}
+
+static gdouble terrain_hmax (FttCell * cell, FttCellFace * face, 
+			     GfsDomain * domain, GfsRefineTerrain * t)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  gdouble dx, dy, max = - G_MAXDOUBLE;
+  gdouble H0 = GFS_VALUE (cell, t->h[0]), H1 = GFS_VALUE (cell, t->h[1]);
+  gdouble H2 = GFS_VALUE (cell, t->h[2]), H3 = GFS_VALUE (cell, t->h[3]);
+
+  for (dx = -1.; dx <= 1.; dx += 2.)
+    for (dy = -1.; dy <= 1.; dy += 2.) {
+      double v = H0 + dx*H1 + dy*H2 + dx*dy*H3;
+      if (v > max) max = v;
+    }
+  return max;
+}
+
+static void refine_terrain_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_refine_terrain_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (name)");
+    return;
+  }
+  GfsRefineTerrain * t = GFS_REFINE_TERRAIN (*o);
+  t->name = g_strdup (fp->token->str);
+  gts_file_next_token (fp);
+
+  rsurfaces_read (&t->rs, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  guint i;
+  for (i = 0; i < NM; i++) {
+    gchar * name = g_strdup_printf ("%s%d", t->name, i);
+    t->h[i] = gfs_domain_get_or_add_variable (domain, name, "Terrain height");
+    g_free (name);
+  }
+  gchar * name = g_strjoin (NULL, t->name, "e", NULL);
+  t->he = gfs_domain_get_or_add_variable (domain, name, "Terrain RMS error");
+  g_free (name);
+  name = g_strjoin (NULL, t->name, "n", NULL);
+  t->hn = gfs_domain_get_or_add_variable (domain, name, "Terrain samples #");
+  g_free (name);
+  name = g_strjoin (NULL, t->name, "dmin", NULL);
+  t->hdmin = gfs_domain_get_or_add_variable (domain, name, "Minimum data height");
+  g_free (name);
+  name = g_strjoin (NULL, t->name, "dmax", NULL);
+  t->hdmax = gfs_domain_get_or_add_variable (domain, name, "Maximum data height");
+  g_free (name);
+
+  GfsDerivedVariableInfo v;
+
+  v.name = g_strjoin (NULL, t->name, "min", NULL);
+  v.description = "Minimum terrain height";
+  v.func = terrain_hmin;
+  v.data = t;
+  if (!gfs_domain_add_derived_variable (domain, v)) {
+    gts_file_error (fp, "derived variable `%s' already defined", v.name);
+    g_free (v.name);
+    return;
+  }
+  g_free (v.name);
+
+  v.name = g_strjoin (NULL, t->name, "max", NULL);
+  v.description = "Maximum terrain height";
+  v.func = terrain_hmax;
+  v.data = t;
+  if (!gfs_domain_add_derived_variable (domain, v)) {
+    gts_file_error (fp, "derived variable `%s' already defined", v.name);
+    g_free (v.name);
+    return;
+  }
+  g_free (v.name);
+
+  gfs_function_read (t->criterion, domain, fp);
+}
+
+static void refine_terrain_write (GtsObject * o, FILE * fp)
+{
+  GfsRefineTerrain * t = GFS_REFINE_TERRAIN (o);
+  (* GTS_OBJECT_CLASS (gfs_refine_terrain_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s", t->name);
+  rsurfaces_write (&t->rs, fp);
+  gfs_function_write (t->criterion, fp);
+}
+
+static void gfs_refine_terrain_class_init (GfsRefineClass * klass)
+{
+  klass->refine = terrain_refine;
+
+  GTS_OBJECT_CLASS (klass)->destroy = refine_terrain_destroy;
+  GTS_OBJECT_CLASS (klass)->read = refine_terrain_read;
+  GTS_OBJECT_CLASS (klass)->write = refine_terrain_write;
+}
+
+static void gfs_refine_terrain_init (GfsRefineTerrain * t)
+{
+  t->criterion = gfs_function_new (gfs_function_class (), 0.);
+  t->rs.basename = g_strdup ("*");
+}
+
+GfsRefineClass * gfs_refine_terrain_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_terrain_info = {
+      "GfsRefineTerrain",
+      sizeof (GfsRefineTerrain),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_terrain_class_init,
+      (GtsObjectInitFunc) gfs_refine_terrain_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_refine_class ()),
+				  &gfs_refine_terrain_info);
+  }
+
+  return klass;
+}
+
+/* GfsSurfaceTerrain: Header */
+
+typedef struct _GfsSurfaceTerrain         GfsSurfaceTerrain;
+
+struct _GfsSurfaceTerrain {
+  /*< private >*/
+  GfsGenericSurface parent;
+  GfsVariable * h[NM];
+  gdouble scale;
+
+  /*< public >*/
+  gchar * name;
+};
+
+#define GFS_SURFACE_TERRAIN(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSurfaceTerrain,\
+					         gfs_surface_terrain_class ())
+#define GFS_IS_SURFACE_TERRAIN(obj)         (gts_object_is_from_class (obj,\
+						 gfs_surface_terrain_class ()))
+
+GfsGenericSurfaceClass * gfs_surface_terrain_class  (void);
+
+/* GfsSurfaceTerrain: Object */
+
+static void gfs_surface_terrain_read (GtsObject ** o, GtsFile * fp)
+{
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a variable name");
+    return;
+  }
+  GfsSurfaceTerrain * t = GFS_SURFACE_TERRAIN (*o);
+  t->name = g_strdup (fp->token->str);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  guint i;
+  for (i = 0; i < NM; i++) {
+    gchar * name = g_strdup_printf ("%s%d", t->name, i);
+    t->h[i] = gfs_variable_from_name (domain->variables, name);
+    if (!t->h[i]) {
+      gts_file_error (fp, "%s is not a valid variable name", name);
+      g_free (name);
+      return;
+    }
+    t->h[i]->coarse_fine = terrain_coarse_fine;
+    g_free (name);
+  }
+  gts_file_next_token (fp);
+}
+
+static void gfs_surface_terrain_write (GtsObject * o, FILE * fp)
+{
+  fprintf (fp, " %s", GFS_SURFACE_TERRAIN (o)->name);
+}
+
+static void gfs_surface_terrain_destroy (GtsObject * object)
+{
+  g_free (GFS_SURFACE_TERRAIN (object)->name);
+  (* GTS_OBJECT_CLASS (gfs_surface_terrain_class ())->parent_class->destroy)
+    (object);
+}
+
+static GfsGenericSurface * cell_is_cut (FttCell * cell, GfsGenericSurface * s1,
+					gboolean flatten, gint maxlevel)
+{
+  g_assert (!flatten); /* not implemented */
+  if (!FTT_CELL_IS_LEAF (cell))
+    return s1;
+  return GFS_VALUE (cell, GFS_SURFACE_TERRAIN (s1)->h[0]) != G_MAXDOUBLE ? s1 : NULL;
+}
+
+static gdouble zscale (GfsSurfaceTerrain * t)
+{
+  if (t->scale == 0.) {
+    FttVector p = {0.,0.,1.};
+    gfs_simulation_map (gfs_object_simulation (t), &p);
+    t->scale = p.z;
+  }
+  return t->scale;
+}
+
+static guint surface_segment_intersection (GfsGenericSurface * s1,
+					   FttCell * cell,
+					   GfsSegment * I)
+{
+  I->n = 0;
+  I->x = 0.;
+  I->inside = 0;
+
+  FttVector pE, pD;
+  pE.x = I->E->x; pE.y = I->E->y;
+  pD.x = I->D->x; pD.y = I->D->y;
+  GfsSurfaceTerrain * t = GFS_SURFACE_TERRAIN (s1);
+  gdouble vE = I->E->z - cell_value (cell, t->h, pE)*zscale (t);
+  gdouble vD = I->D->z - cell_value (cell, t->h, pD)*zscale (t);
+  
+  if ((vE > 0. && vD <= 0.) || (vE <= 0. && vD > 0.)) {
+    I->n = 1;
+    I->inside = vE > 0. ? -1 : 1;
+    I->x = vE/(vE - vD);
+#if DEBUG
+    gdouble size = ftt_cell_size (cell)/2.;
+    FttVector q;
+    ftt_cell_pos (cell, &q);
+    pE.x = (pE.x - q.x)/size;
+    pE.y = (pE.y - q.y)/size;
+    pD.x = (pD.x - q.x)/size;
+    pD.y = (pD.y - q.y)/size;
+    fprintf (stderr, "p %g %g %g %g %g %g %g %d %g %g %g %g\n", 
+	     I->D->x, I->D->y, I->D->z,
+	     I->E->x, I->E->y, I->E->z,
+	     I->x,
+	     ftt_cell_level (cell),
+	     pE.x, pE.y, pD.x, pD.y);
+    fprintf (stderr, "q %g %g %g\nq %g %g %g\nq\nq\n",
+	     I->D->x, I->D->y, I->D->z,
+	     I->E->x, I->E->y, I->E->z);
+    fprintf (stderr, "i %g %g %g\n",
+	     I->E->x + I->x*(I->D->x - I->E->x),
+	     I->E->y + I->x*(I->D->y - I->E->y),
+	     I->E->z + I->x*(I->D->z - I->E->z));
+#endif
+  }
+  return I->n;
+}
+
+static void surface_segment_normal (GfsGenericSurface * s1,
+				    FttCell * cell,
+				    GfsSegment * I,
+				    GtsVector n)
+{
+  GfsVariable ** h = GFS_SURFACE_TERRAIN (s1)->h;
+  gdouble size = ftt_cell_size (cell)/2.;
+  FttVector p, q;
+  ftt_cell_pos (cell, &q);
+  p.x = I->E->x + I->x*(I->D->x - I->E->x);
+  p.y = I->E->y + I->x*(I->D->y - I->E->y);
+  p.x = (p.x - q.x)/size;
+  p.y = (p.y - q.y)/size;
+  n[0] = - (GFS_VALUE (cell, h[1]) + GFS_VALUE (cell, h[3])*p.y)/size;
+  n[1] = - (GFS_VALUE (cell, h[2]) + GFS_VALUE (cell, h[3])*p.x)/size;
+  n[2] = 1./zscale (GFS_SURFACE_TERRAIN (s1));
+}
+
+static void gfs_surface_terrain_class_init (GfsGenericSurfaceClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_surface_terrain_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_surface_terrain_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_surface_terrain_destroy;
+
+  klass->cell_is_cut = cell_is_cut;
+  klass->segment_intersection = surface_segment_intersection;
+  klass->segment_normal = surface_segment_normal;
+}
+
+GfsGenericSurfaceClass * gfs_surface_terrain_class (void)
+{
+  static GfsGenericSurfaceClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_surface_terrain_info = {
+      "GfsSurfaceTerrain",
+      sizeof (GfsSurfaceTerrain),
+      sizeof (GfsGenericSurfaceClass),
+      (GtsObjectClassInitFunc) gfs_surface_terrain_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_surface_class ()),
+				  &gfs_surface_terrain_info);
+  }
+
+  return klass;
+}
+
+/* GfsTerrain: Header */
+
+#define GFS_IS_TERRAIN(obj)         (gts_object_is_from_class (obj,\
+						 gfs_terrain_class ()))
+
+GfsEventClass * gfs_terrain_class  (void);
+
+/* GfsTerrain: Object */
+
+static void terrain_init (GfsSolid * s)
+{
+  gts_object_destroy (GTS_OBJECT (s->s));
+  s->s = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_terrain_class ())));
+}
+
+GfsEventClass * gfs_terrain_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_terrain_info = {
+      "GfsTerrain",
+      sizeof (GfsSolid),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) terrain_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_solid_class ()),
+				  &gfs_terrain_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableTerrain: header */
+
+typedef struct _GfsVariableTerrain                GfsVariableTerrain;
+
+struct _GfsVariableTerrain {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsVariable * p, * H;
+  RSurfaces rs;
+};
+
+#define GFS_VARIABLE_TERRAIN(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableTerrain,\
+					           gfs_variable_terrain_class ())
+#define GFS_IS_VARIABLE_TERRAIN(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_terrain_class ()))
+
+GfsVariableClass * gfs_variable_terrain_class  (void);
+
+/* GfsVariableTerrain: Object */
+
+static void variable_terrain_destroy (GtsObject * o)
+{
+  rsurfaces_destroy (&GFS_VARIABLE_TERRAIN (o)->rs);
+
+  (* GTS_OBJECT_CLASS (gfs_variable_terrain_class ())->parent_class->destroy) (o);
+}
+
+static void none (FttCell * parent, GfsVariable * v)
+{
+}
+
+static void variable_terrain_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  GfsVariableTerrain * t = GFS_VARIABLE_TERRAIN (v);
+  GfsSimulation * sim = GFS_SIMULATION (v->domain);
+  FttCellChildren child;
+  guint n;
+
+  /* Reconstruct terrain */
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++) 
+    if (child.c[n]) {
+      Polygon poly;
+      RSurfaceRect rect;
+      RSurfaceSum s;
+      guint i;
+      polygon_init (sim, &poly, child.c[n], &t->rs);
+      r_surface_sum_init (&s);
+      rect[0].l = poly.c.x - poly.h/2.; rect[0].h = poly.c.x + poly.h/2.; 
+      rect[1].l = poly.c.y - poly.h/2.; rect[1].h = poly.c.y + poly.h/2.; 
+      for (i = 0; i < poly.rs->nrs; i++)
+	r_surface_query_region_sum (poly.rs->rs[i],
+				    (RSurfaceCheck) polygon_includes,
+				    (RSurfaceCheck) polygon_intersects, &poly, 
+				    rect, &s);
+      if (s.n > 0)
+	GFS_VALUE (child.c[n], v) = s.H0/s.n/sim->physical_params.L;
+      else {
+	GFS_VALUE (child.c[n], v) = GFS_VALUE (parent, v);
+	if (!GFS_CELL_IS_BOUNDARY (parent)) {
+	  FttVector p;
+	  FttComponent c;
+	  
+	  ftt_cell_relative_pos (child.c[n], &p);
+	  for (c = 0; c < FTT_DIMENSION; c++)
+	    GFS_VALUE (child.c[n], v) += (&p.x)[c]*gfs_center_minmod_gradient (parent, c, v->i);
+	}
+      }
+    }
+
+  /* If we are part of GfsRiver, reconstruct H and P */
+  if (t->H) {
+    /* Reconstruct H */
+    if (GFS_VALUE (parent, t->p) < GFS_RIVER_DRY) {
+      /* Dry cell */
+      FttCellNeighbors neighbor;
+      ftt_cell_neighbors (parent, &neighbor);
+      FttDirection d;
+      gdouble H = 0., s = 0.;
+      for (d = 0; d < FTT_NEIGHBORS; d++)
+	if (neighbor.c[d] && GFS_VALUE (neighbor.c[d], t->p) >= GFS_RIVER_DRY) {
+	  H += GFS_VALUE (neighbor.c[d], t->H);
+	  s += 1.;
+	}
+      if (s > 0.) {
+	H /= s; /* average H of neighbouring wet cells */
+	for (n = 0; n < FTT_CELLS; n++)
+	  if (child.c[n])
+	    GFS_VALUE (child.c[n], t->H) = H;
+      }
+      else { /* surrounded by dry cells */
+	for (n = 0; n < FTT_CELLS; n++)
+	  if (child.c[n])
+	    GFS_VALUE (child.c[n], t->H) = GFS_VALUE (child.c[n], v); /* dry cell */
+      }
+    }
+    else {
+      /* wet cell */
+      GfsVariable * v = t->H;
+      for (n = 0; n < FTT_CELLS; n++)
+	if (child.c[n])
+	  GFS_VALUE (child.c[n], v) = GFS_VALUE (parent, v);
+      
+      if (!GFS_CELL_IS_BOUNDARY (parent)) {
+	FttVector g;
+	FttComponent c;
+	FttCellNeighbors neighbor;
+	ftt_cell_neighbors (parent, &neighbor);
+
+	for (c = 0; c < FTT_DIMENSION; c++)
+	  if (neighbor.c[2*c] && GFS_VALUE (neighbor.c[2*c], t->p) >= GFS_RIVER_DRY &&
+	      neighbor.c[2*c + 1] && GFS_VALUE (neighbor.c[2*c + 1], t->p) >= GFS_RIVER_DRY)
+	    (&g.x)[c] = gfs_center_minmod_gradient (parent, c, v->i);
+	  else
+	    (&g.x)[c] = 0.;
+	
+	for (n = 0; n < FTT_CELLS; n++) 
+	  if (child.c[n]) {
+	    FttVector p;
+	    
+	    ftt_cell_relative_pos (child.c[n], &p);
+	    for (c = 0; c < FTT_DIMENSION; c++)
+	      GFS_VALUE (child.c[n], v) += (&p.x)[c]*(&g.x)[c];
+	  }
+      }
+    }
+    /* Deduce P from the reconstruction of Zb and H */
+    for (n = 0; n < FTT_CELLS; n++)
+      if (child.c[n]) {
+	GFS_VALUE (child.c[n], t->p) = MAX (0., (GFS_VALUE (child.c[n], t->H) - 
+						 GFS_VALUE (child.c[n], v)));
+	GFS_VALUE (child.c[n], t->H) = GFS_VALUE (child.c[n], t->p) + GFS_VALUE (child.c[n], v);
+      }
+  }
+}
+
+static void variable_terrain_fine_coarse (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  guint n;
+
+  /* Reconstruct terrain (weighted average) */
+  gdouble Zb = 0., sa = 0.;
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++) 
+    if (child.c[n]) {
+      gdouble a = GFS_IS_MIXED (child.c[n]) ? GFS_STATE (child.c[n])->solid->a : 1.;
+      Zb += GFS_VALUE (child.c[n], v)*a;
+      sa += a;
+    }
+  if (sa > 0.)
+    GFS_VALUE (parent, v) = Zb/sa;
+
+  /* If we are part of GfsRiver, reconstruct H and P */
+  GfsVariableTerrain * t = GFS_VARIABLE_TERRAIN (v);
+  if (t->H) {
+    /* Reconstruct H */
+    gdouble H = 0., sa = 0.;
+    for (n = 0; n < FTT_CELLS; n++) 
+      if (child.c[n] && GFS_VALUE (child.c[n], t->p) >= GFS_RIVER_DRY) {
+	gdouble a = GFS_IS_MIXED (child.c[n]) ? GFS_STATE (child.c[n])->solid->a : 1.;
+	H += GFS_VALUE (child.c[n], t->H)*a;
+	sa += a;
+      }
+    if (sa > 0.) {
+      GFS_VALUE (parent, t->H) = H/sa;
+      GFS_VALUE (parent, t->p) = MAX (0., GFS_VALUE (parent, t->H) - GFS_VALUE (parent, v));
+    }
+    else { /* dry cell */
+      GFS_VALUE (parent, t->p) = 0.;
+      GFS_VALUE (parent, t->H) = GFS_VALUE (parent, v);
+    }
+  }
+}
+
+static void variable_terrain_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_terrain_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsVariableTerrain * v = GFS_VARIABLE_TERRAIN (*o);
+  rsurfaces_read (&v->rs, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsVariable * v1 = GFS_VARIABLE1 (*o);
+  v1->units = 1.;
+  g_free (v1->description);
+  v1->description = g_strdup ("Terrain");
+  v1->coarse_fine = variable_terrain_coarse_fine;
+  v1->fine_coarse = variable_terrain_fine_coarse;
+
+  GfsSimulation * sim = gfs_object_simulation (*o);
+  if (GFS_IS_RIVER (sim) && fp->type == '{') {
+    gboolean reconstruct = FALSE;
+    GtsFileVariable var[] = {
+      {GTS_INT, "reconstruct", TRUE, &reconstruct},
+      {GTS_NONE}
+    };
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+    if (reconstruct) {
+      v->p = GFS_RIVER (sim)->v[0];
+      v->H = GFS_RIVER (sim)->H;
+      /* the coarse -> fine and fine -> coarse interpolations of p and H
+	 are taken over by variable_terrain_coarse_fine (below )*/
+      v->p->coarse_fine = none;
+      v->H->coarse_fine = none;
+      v->p->fine_coarse = none;
+      v->H->fine_coarse = none;
+    }
+  }
+}
+
+static void variable_terrain_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_terrain_class ())->parent_class->write) (o, fp);
+
+  rsurfaces_write (&GFS_VARIABLE_TERRAIN (o)->rs, fp);
+  if (GFS_VARIABLE_TERRAIN (o)->H)
+    fputs (" { reconstruct = 1 }", fp);
+}
+
+static void variable_terrain_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = variable_terrain_destroy;
+  klass->read = variable_terrain_read;
+  klass->write = variable_terrain_write;
+}
+
+static void variable_terrain_init (GfsVariableTerrain * v)
+{
+  v->rs.basename = g_strdup ("*");
+}
+
+GfsVariableClass * gfs_variable_terrain_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_terrain_info = {
+      "GfsVariableTerrain",
+      sizeof (GfsVariableTerrain),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_terrain_class_init,
+      (GtsObjectInitFunc) variable_terrain_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_terrain_info);
+  }
+
+  return klass;
+}
+
+/* Initialize module */
+
+/* only define gfs_module_name for "official" modules (i.e. those installed in
+   GFS_MODULES_DIR) */
+const gchar gfs_module_name[] = "terrain";
+const gchar * g_module_check_init (void);
+
+const gchar * g_module_check_init (void)
+{
+  gchar * path = getenv ("GFS_TERRAIN_PATH");
+  if (path && path[0] != '\0')
+    default_path = path;
+  gfs_refine_terrain_class ();
+  gfs_terrain_class ();
+  gfs_variable_terrain_class ();
+  return NULL;
+}
diff --git a/modules/tide.mod b/modules/tide.mod
new file mode 100644
index 0000000..15d8ffa
--- /dev/null
+++ b/modules/tide.mod
@@ -0,0 +1,406 @@
+/* Gerris - The GNU Flow Solver                       (-*-C-*-)
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#define _XOPEN_SOURCE /* glibc2 needs this for strptime() */
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <stdlib.h>
+#include "fes2004/fes2004_lib.h"
+#include "gfsconfig.h"
+#include "variable.h"
+
+/* Heavily based on GfsBcFlather */
+
+static gchar * reference = "1950/01/01-00:00:00-UTC";
+static gdouble deltat = 0.;
+
+/* GfsBcTide: Header */
+
+typedef struct _GfsBcTide         GfsBcTide;
+
+struct _GfsBcTide {
+  /*< private >*/
+  GfsBcValue parent;
+  gdouble ** amplitude, ** phase, x, size;
+
+  /*< public >*/
+  GfsVariable * h, * p;
+};
+
+#define GFS_BC_TIDE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsBcTide,\
+					         gfs_bc_tide_class ())
+#define GFS_IS_BC_TIDE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_tide_class ()))
+
+GfsBcClass * gfs_bc_tide_class  (void);
+
+/* GfsBcTide: Object */
+
+#define N  64 /* number of discretisation points */
+
+#define NM 14 /* number of tidal modes (must match those of FES2004) */
+
+static void bc_tide_write (GtsObject * o, FILE * fp)
+{
+  GfsBcTide * bc = GFS_BC_TIDE (o);
+  guint i, j;
+
+  (* GTS_OBJECT_CLASS (gfs_bc_tide_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s %s {\n", bc->h->name, bc->p->name);
+  for (i = 0; i < N; i++) {
+    for (j = 0; j < NM; j++)
+      fprintf (fp, "  %g %g\n", bc->amplitude[j][i], bc->phase[j][i]);
+  }
+  fputc ('}', fp);
+}
+
+static void set_gradient_boundary (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_GRADIENT_BOUNDARY;
+}
+
+static void bc_tide_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBcTide * bc = GFS_BC_TIDE (*o);
+  GfsDomain * domain = gfs_box_domain (GFS_BC (bc)->b->box);
+
+  (* GTS_OBJECT_CLASS (gfs_bc_tide_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsBoundary * b = GFS_BC (bc)->b;
+  if (b->d > FTT_BOTTOM) {
+    gts_file_error (fp, "GfsBcTide cannot be used for 3D boundaries");
+    return;
+  }
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (h)");
+    return;
+  }
+  bc->h = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (bc->h == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (p)");
+    return;
+  }
+  bc->p = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (bc->p == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  ftt_cell_traverse (b->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) set_gradient_boundary, NULL);
+
+  guint i;  
+  gpointer tmp = g_malloc0 (N*NM*sizeof (double));
+  bc->amplitude = g_malloc (N*sizeof (double *));
+  for (i = 0; i < N; i++)
+    bc->amplitude[i] = tmp + i*NM*sizeof (double);
+  tmp = g_malloc0 (N*NM*sizeof (double));
+  bc->phase = g_malloc (N*sizeof (double *));
+  for (i = 0; i < N; i++)
+    bc->phase[i] = tmp + i*NM*sizeof (double);
+
+  FttCellFace face;
+  face.cell = b->root;
+  face.d = b->d;
+  FttVector p;
+  ftt_face_pos (&face, &p);
+  FttComponent c = face.d < FTT_TOP ? FTT_Y : FTT_X;
+  bc->size = ftt_cell_size (b->root);
+  (&p.x)[c] -= bc->size/2.;
+  bc->x = (&p.x)[c];
+
+  if (fp->type == '{') {
+    /* read embedded coefficients */
+    guint j;
+    fp->scope_max++;
+    gts_file_next_token (fp);
+    for (i = 0; i < N; i++) {
+      for (j = 0; j < NM; j++) {
+	while (fp->type == '\n') gts_file_next_token (fp);
+	if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+	  gts_file_error (fp, "expecting a number (amplitude[%d][%d])", j, i);
+	  return;
+	}
+	bc->amplitude[j][i] = atof (fp->token->str);
+	gts_file_next_token (fp);
+	if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+	  gts_file_error (fp, "expecting a number (phase[%d][%d])", j, i);
+	  return;
+	}
+	bc->phase[j][i] = atof (fp->token->str);
+	gts_file_next_token (fp);
+      }
+    }
+    while (fp->type == '\n') gts_file_next_token (fp);
+    if (fp->type != '}') {
+      gts_file_error (fp, "expecting a closing brace");
+      return;
+    }
+    fp->scope_max--;
+    gts_file_next_token (fp);
+  }
+  else {
+    /* extract FES2004 tidal coefficients */
+    gchar * fname = getenv ("GFS_FES2004") ?
+      g_strdup (getenv ("GFS_FES2004"))
+      :
+      g_strjoin ("/", GFS_MODULES_DIR, "tide.fes2004.nc", NULL);
+    FILE * f = fopen (fname, "r");
+    if (f == NULL) {
+      gts_file_error (fp, "cannot open file `%s': %s", fname, strerror (errno));
+      g_free (fname);
+      return;
+    }
+    fclose (f);
+
+    double * lon = g_malloc (N*sizeof (double));
+    double * lat = g_malloc (N*sizeof (double));
+    gdouble dh = bc->size/(N - 1);
+    for (i = 0; i < N; i++, (&p.x)[c] += dh) {
+      FttVector mp = p;
+      gfs_simulation_map_inverse (GFS_SIMULATION (gfs_box_domain (b->box)), &mp);
+      lon[i] = mp.x; lat[i] = mp.y;
+    }
+
+    fes2004_extraction (fname, N, lat, lon, bc->amplitude, bc->phase, 1);
+
+    g_free (fname);
+    g_free (lon);
+    g_free (lat);
+  }
+}
+
+static void bc_tide_destroy (GtsObject * o)
+{
+  GfsBcTide * bc = GFS_BC_TIDE (o);
+
+  if (bc->amplitude) {
+    g_free (bc->amplitude[0]);
+    g_free (bc->amplitude);
+  }
+  if (bc->phase) {
+    g_free (bc->phase[0]);
+    g_free (bc->phase);
+  }
+    
+  (* GTS_OBJECT_CLASS (gfs_bc_tide_class ())->parent_class->destroy) (o);
+}
+
+static tidal_wave wave[NM];
+
+static gdouble amplitude_value (FttCellFace * face, GfsBcTide * bc, gdouble t)
+{
+  FttComponent c = face->d < FTT_TOP ? FTT_Y : FTT_X;
+  FttVector p;
+  ftt_face_pos (face, &p);
+  guint i = floor (((&p.x)[c] - bc->x)/bc->size*(N - 1));
+  g_assert (i < N - 1);
+  if (bc->amplitude[i][2] < 0. && bc->amplitude[i+1][2] < 0.)
+    return G_MAXDOUBLE;
+
+  gdouble dh = bc->size/(N - 1);
+  gdouble a = ((&p.x)[c] - bc->x - dh*i)/dh;
+  if (bc->amplitude[i][2] < 0.)
+    a = 1.;
+  if (bc->amplitude[i+1][2] < 0.)
+    a = 0.;
+
+  gdouble prediction = 0.;
+  guint j;
+  for (j = 0; j < NM; j++) {
+    fcomplex Z1, Z2, Z;
+    Z1.reel = bc->amplitude[i][j]*cos (- bc->phase[i][j]*M_PI/180.);
+    Z1.imag = bc->amplitude[i][j]*sin (- bc->phase[i][j]*M_PI/180.);
+    Z2.reel = bc->amplitude[i+1][j]*cos (- bc->phase[i+1][j]*M_PI/180.);
+    Z2.imag = bc->amplitude[i+1][j]*sin (- bc->phase[i+1][j]*M_PI/180.);
+    Z.reel = (1. - a)*Z1.reel + a*Z2.reel;
+    Z.imag = (1. - a)*Z1.imag + a*Z2.imag;
+    prediction += Tide_prediction (t, wave[j], Z, 0, 0);
+  }
+  return prediction;
+}
+
+static gdouble tide_value (FttCellFace * f, GfsBc * b)
+{
+  /* fixme: this will not work for multilayer domains */
+  guint d, nb = 0;
+  FttCellNeighbors n;
+  gdouble H;
+
+  ftt_cell_neighbors (f->neighbor, &n);
+  for (d = 0; d < FTT_NEIGHBORS_2D; d++)
+    if (n.c[d] != NULL && GFS_CELL_IS_BOUNDARY(n.c[d]) && nb++ > 0)
+      /* if the boundary cell is bounded by more than one boundary -> no flux */
+      return 0.;
+
+  H = gfs_face_interpolated_value (f, GFS_BC_TIDE (b)->h->i);
+  if (H > 2e-3) { /* fixme: 2e-3 is an arbitrary constant which should be a parameter or sthg*/
+    GfsSimulation * sim = GFS_SIMULATION (gfs_box_domain (b->b->box));
+    gdouble a = amplitude_value (f, GFS_BC_TIDE (b), sim->time.t + deltat);
+    if (a < G_MAXDOUBLE) {
+      gdouble cg = sqrt (sim->physical_params.g*H);
+      
+      a *= sim->physical_params.g/5000.; /* fixme: reference depth is fixed at 5000 meters */
+      return gfs_function_face_value (GFS_BC_VALUE (b)->val, f) +
+	(FTT_FACE_DIRECT (f) ? -1. : 1.)*
+	(GFS_VARIABLE (f->neighbor, GFS_BC_TIDE (b)->p->i) - a)*
+	cg/sim->physical_params.g
+#if !FTT_2D
+	/H
+#endif
+	;
+    }
+  }
+  return 0.;
+}
+
+static void tide (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  g_assert (ftt_cell_neighbor (f->cell, f->d) == f->neighbor);
+  GFS_VARIABLE (f->cell, b->v->i) = 2.*tide_value (f, b) - GFS_VARIABLE (f->neighbor, b->v->i);
+}
+
+static void homogeneous_tide (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  GFS_VARIABLE (f->cell, b->v->i) = - GFS_VARIABLE (f->neighbor, b->v->i);
+}
+
+static void face_tide (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  GFS_STATE (f->cell)->f[f->d].v = tide_value (f, b);
+}
+
+static void gfs_bc_tide_class_init (GtsObjectClass * klass)
+{
+  klass->write   = bc_tide_write;
+  klass->read    = bc_tide_read;
+  klass->destroy = bc_tide_destroy;
+}
+
+static void gfs_bc_tide_init (GfsBc * bc)
+{
+  bc->bc =             (FttFaceTraverseFunc) tide;
+  bc->homogeneous_bc = (FttFaceTraverseFunc) homogeneous_tide;
+  bc->face_bc =        (FttFaceTraverseFunc) face_tide;
+}
+
+GfsBcClass * gfs_bc_tide_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_tide_info = {
+      "GfsBcTide",
+      sizeof (GfsBcTide),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_tide_class_init,
+      (GtsObjectInitFunc) gfs_bc_tide_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_tide_info);
+  }
+
+  return klass;
+}
+
+/* Initialize module */
+
+/* only define gfs_module_name for "official" modules (i.e. those installed in
+   GFS_MODULES_DIR) */
+const gchar gfs_module_name[] = "tide";
+const gchar * g_module_check_init (void);
+void          gfs_module_read     (GtsFile * fp);
+void          gfs_module_write    (FILE * fp);
+
+const gchar * g_module_check_init (void)
+{
+  wave[0] = w2N2;
+  wave[1] = wK1;
+  wave[2] = wK2;
+  wave[3] = wM2;
+  wave[4] = wM4;
+  wave[5] = wMf;
+  wave[6] = wMm;
+  wave[7] = wMSqm;
+  wave[8] = wMtm;
+  wave[9] = wN2;
+  wave[10] = wO1;
+  wave[11] = wP1;
+  wave[12] = wQ1;
+  wave[13] = wS2;
+  gfs_bc_tide_class ();
+  return NULL;
+}
+
+#define TIME_FORMAT "%Y/%m/%d-%T"
+
+void gfs_module_read (GtsFile * fp)
+{
+  g_return_if_fail (fp != NULL);
+  
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_STRING, "reference",  TRUE},
+      {GTS_NONE}
+    };
+    var[0].data = &reference;
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+
+    if (var[0].set) {
+      struct tm timeref;
+      time_t tref, t0;
+      memset (&timeref, 0, sizeof(struct tm));
+      strptime ("1950/01/01-00:00:00-UTC", TIME_FORMAT, &timeref);
+      tref = mktime (&timeref);
+      memset (&timeref, 0, sizeof(struct tm));
+      if (!strptime (reference, TIME_FORMAT, &timeref)) {
+	gts_file_variable_error (fp, var, "reference", "error parsing date format");
+	return;
+      }
+      t0 = mktime (&timeref);
+      deltat = difftime (t0, tref)/3600.;
+    }
+  }
+}
+
+void gfs_module_write (FILE * fp)
+{
+  g_return_if_fail (fp != NULL);
+ 
+  fprintf (fp, " { reference = %s }", reference);
+}
diff --git a/modules/wavewatch.mod b/modules/wavewatch.mod
new file mode 100644
index 0000000..7028c27
--- /dev/null
+++ b/modules/wavewatch.mod
@@ -0,0 +1,321 @@
+/* Gerris - The GNU Flow Solver                       (-*-C-*-)
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include "wave.h"
+#include "config.h"
+#if WW3_VERSION == 222
+#  include "wavewatch/wavewatch_222.h"
+#elif WW3_VERSION == 312
+#  include "wavewatch/wavewatch_312.h"
+#else /* 3.14 */
+#  include "wavewatch/wavewatch_314.h"
+#endif
+
+#define DEBUG 0
+
+static double frequency (int ik)
+{
+  return GFS_WAVE_F0*pow(GFS_WAVE_GAMMA, ik);
+}
+
+#if DEBUG      
+static double theta (guint ith, guint ntheta)
+{
+  return 2.*M_PI*ith/ntheta;
+}
+#endif
+
+typedef struct {
+  GfsWave * wave;
+  GfsVariable * ustar, * fpi, * u10, * v10, * as;
+  REAL * A;     /* Actions (NK*NTHETA) */
+  REAL * CG;    /* Group velocities (NK) */
+  REAL * WN;    /* Wavenumbers (NK) */
+  REAL * ALPHA; /* Nondimensional 1-D spectrum (NK) */  
+} SourceParams;
+
+static void energy_to_action (FttCell * cell, SourceParams * p)
+{
+  guint i, j;
+  REAL * A = p->A;
+  for (i = 0; i < p->wave->nk; i++)
+    for (j = 0; j < p->wave->ntheta; j++) {
+      *A = GFS_VALUE (cell, p->wave->F[i][j])*p->CG[i]/(2.*M_PI*frequency (i));
+      if (*A < 0.)
+        *A = 0.;
+      A++;
+    }
+}
+
+static void action_to_energy (FttCell * cell, SourceParams * p)
+{
+  guint i, j;
+  REAL * A = p->A;
+  for (i = 0; i < p->wave->nk; i++)
+    for (j = 0; j < p->wave->ntheta; j++) {
+      GFS_VALUE (cell, p->wave->F[i][j]) = *A*(2.*M_PI*frequency (i))/p->CG[i];
+      A++;
+    }
+}
+
+static void stability_correction (FttCell * cell, SourceParams * p, REAL * U10ABS, REAL * U10DIR)
+{
+  double u10 = p->u10 ? GFS_VALUE (cell, p->u10) : 0.;
+  double v10 = p->v10 ? GFS_VALUE (cell, p->v10) : 0.;
+  *U10ABS = sqrt (u10*u10 + v10*v10);
+  *U10DIR = atan2 (v10, u10);
+  if (p->as) {
+    /* see p.24 of wavewatch manual version 3.12 */
+    double shstab = 1.4, ofstab = -0.01, ccng = -0.1, ccps = 0.1, ffng = -150., ffps = 150.;
+    double zwind = 10.;  /* height at which the wind is defined */
+    double grav = 9.81; /* acceleration of gravity */
+    double stab0 = zwind*grav/273.;
+    double max = MAX (5., *U10ABS);
+    double stab = stab0*GFS_VALUE (cell, p->as)/(max*max);
+    stab = MAX (-1., MIN (1., stab));
+    double tharg1 = MAX (0., ffng*(stab - ofstab));
+    double tharg2 = MAX (0., ffps*(stab - ofstab));
+    double cor1 = ccng*tanh (tharg1);
+    double cor2 = ccps*tanh (tharg2);
+    double cor = sqrt ((1. + cor1 + cor2)/shstab);
+    *U10ABS /= cor;
+  }
+}
+
+static void source (FttCell * cell, SourceParams * p)
+{
+  energy_to_action (cell, p);
+
+  REAL DEPTH = 1000.; /* fixme: depth is fixed at 1000 m for now */
+  REAL U10ABS, U10DIR;
+
+  stability_correction (cell, p, &U10ABS, &U10DIR);
+
+  REAL USTAR = GFS_VALUE (cell, p->ustar);
+  REAL FPI = GFS_VALUE (cell, p->fpi);
+  REAL DTG = GFS_SIMULATION (p->wave)->advection_params.dt*3600.;
+
+  REAL EMEAN, FMEAN, WMEAN, AMAX;
+  REAL CD, Z0;
+  REAL DTDYN, FCUT;
+  
+#if WW3_VERSION == 222
+  REAL DTMIN = DTG/10., DTMAX = DTG;
+  W3SRCE (p->A, p->A, p->ALPHA, p->WN, p->CG, &DEPTH, 
+	  &U10ABS, &U10DIR, &USTAR,
+	  &EMEAN, &FMEAN, &WMEAN, &AMAX, 
+	  &FPI, &CD, &Z0, 
+	  &DTDYN, &FCUT, &DTG, &DTMIN, &DTMAX);
+#elif WW3_VERSION == 312
+  INTEGER IX, IY, IMOD = 1;
+  REAL USTDIR;
+  W3SRCE (&IX, &IY, &IMOD, p->A, p->ALPHA, p->WN, p->CG, &DEPTH, 
+	  &U10ABS, &U10DIR, &USTAR, &USTDIR,
+	  &EMEAN, &FMEAN, &WMEAN, &AMAX, 
+	  &FPI, &CD, &Z0, 
+	  &DTDYN, &FCUT, &DTG);
+#else /* 3.14 */
+  INTEGER IX, IY, IMOD = 1;
+  REAL AS = p->as ? GFS_VALUE (cell, p->as) : 0.;
+  REAL USTDIR;
+  REAL CX = 0., CY = 0.;
+  W3SRCE (&IX, &IY, &IMOD, p->A, p->ALPHA, p->WN, p->CG, &DEPTH, 
+	  &U10ABS, &U10DIR, &AS, &USTAR, &USTDIR,
+	  &CX, &CY,
+	  &EMEAN, &FMEAN, &WMEAN, &AMAX, 
+	  &FPI, &CD, &Z0, 
+	  &DTDYN, &FCUT, &DTG);
+#endif /* 3.14 */
+
+#if DEBUG
+  guint i, j;
+  for (i = 0; i < p->wave->nk; i++) {
+    for (j = 0; j < p->wave->ntheta; j++)      
+      fprintf (stderr, "%g %g %g\n", frequency (i), theta (j, p->wave->ntheta), 
+	       p->A[j + i*p->wave->ntheta]);
+    fprintf (stderr, "\n");
+  }
+#endif
+
+  action_to_energy (cell, p);
+  GFS_VALUE (cell, p->ustar) = USTAR;
+  GFS_VALUE (cell, p->fpi) = FPI;
+}
+
+static void deletedir (const char * name)
+{
+  gchar * command = g_strconcat ("rm -r -f ", name, NULL);
+  int status = system (command);
+  if (status)
+    g_warning ("could not cleanup wavewatch setup");
+  g_free (command);
+}
+
+static void initialize (GfsWave * wave)
+{
+  static gboolean initialized = FALSE;
+  if (!initialized) {
+
+    /* Creates temporary directory */
+    char template[] = "/tmp/gfswavewatch.XXXXXX", * tmp;
+    tmp = mkdtemp (template);
+    if (tmp == NULL) {
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, 
+	     "wavewatch module: could not create temporary directory\n"
+	     "%s\n", strerror (errno));
+      return;
+    }
+
+    /* Creates wavewatch ww3_grid.inp input file */
+    gchar * sinput = g_strconcat (tmp, "/ww3_grid.inp", NULL);
+    FILE * input = fopen (sinput, "w");
+    g_free (sinput);
+    if (input == NULL) {
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, 
+	     "wavewatch module: could not create input file\n"
+	     "%s\n", strerror (errno));
+      deletedir (tmp);
+      return;      
+    }
+    fprintf (input,
+	     "$\n"
+	     "      'Gerris wavewatch module'\n"
+	     "   %g  %g  %d  %d  0.\n"
+	     "   F F F F F T\n"
+	     "    900. 950. 900. 300.\n"
+	     "END OF NAMELISTS\n",
+	     GFS_WAVE_GAMMA, GFS_WAVE_F0, wave->nk, wave->ntheta);
+
+    /* Dummy wavewatch parameters */
+    static gchar constant_parameters[] =
+      "      3      3\n"
+      "      1000.     1000.     1.\n"
+      "     -1000.    -1000.     1.\n"
+      "     -0.1 2.50  10  -1000. 3 1 '(....)' 'NAME' 'bottom.inp'\n"
+      "  1 1 1\n"
+      "  1 1 1\n"
+      "  1 1 1\n"
+#if WW3_VERSION == 222
+      "      0   0   F\n"
+#else /* version 3.12 and 3.14 */
+      "   10 3 1 '(....)' 'PART' 'mapsta.inp'\n"
+      "      0   0   F\n"
+      "      0   0   F\n"
+      "      0   0\n"
+#endif /* version 3.12 and 3.14 */
+      "     0.    0.    0.    0.       0\n";
+    fputs (constant_parameters, input);
+    fclose (input);
+
+    /* Calls 'ww3_grid' of wavewatch to generate 'mod_def.w3'
+     * required to initialize wavewatch. */
+    char * wdir = getcwd (NULL, 0);
+    char * command = g_strconcat ("cd ",  tmp, " && "
+				  "test -f $HOME/.wwatch3.env && "
+				  "`grep WWATCH3_DIR $HOME/.wwatch3.env | "
+				  "awk '{print $2}'`/exe/ww3_grid > ", wdir, "/log_grid.ww3 && "
+				  "mv mod_def.ww3 ", wdir, " && "
+				  "rm -r -f ", tmp,
+				  NULL);
+    int status = system (command);
+    deletedir (tmp);
+    free (wdir);
+    g_free (command);
+    if (status == -1 || WEXITSTATUS (status) != 0) {
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, 
+	     "wavewatch module: error when running ww3_grid\nsee log_grid.ww3 for details");
+      return;
+    }
+
+    /* Initialize wavewatch */
+    GFSW3INIT ();
+
+    /* cleanup */
+    remove ("mod_def.ww3");
+    initialized = TRUE;
+  }
+}
+
+static void wavewatch_source (GfsWave * wave)
+{
+  GfsDomain * domain = GFS_DOMAIN (wave);
+  SourceParams p;
+
+  gfs_domain_timer_start (domain, "wavewatch_source");
+
+  initialize (wave);
+
+  p.wave = wave;
+  p.A = g_malloc (wave->nk*wave->ntheta*sizeof (REAL));
+  p.CG = g_malloc (wave->nk*sizeof (REAL));
+  p.WN = g_malloc (wave->nk*sizeof (REAL));
+  p.ALPHA = g_malloc (wave->nk*sizeof (REAL));
+  p.ustar = gfs_variable_from_name (domain->variables, "Ustar");
+  p.fpi = gfs_variable_from_name (domain->variables, "Fpi");
+  p.u10 = gfs_variable_from_name (domain->variables, "U10");
+  p.v10 = gfs_variable_from_name (domain->variables, "V10");
+  p.as = gfs_variable_from_name (domain->variables, "AS");
+
+  guint i;
+  for (i = 0; i < wave->nk; i++) {
+    REAL omega = 2.*M_PI*frequency (i);
+    p.WN[i] = omega*omega/9.81;
+    p.CG[i] = 9.81/omega/2.;
+  }
+
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) source, &p);
+
+  g_free (p.A);
+  g_free (p.CG);
+  g_free (p.WN);
+  g_free (p.ALPHA);
+
+  gfs_domain_timer_stop (domain, "wavewatch_source");
+}
+
+/* Initialize module */
+
+/* only define gfs_module_name for "official" modules (i.e. those installed in
+   GFS_MODULES_DIR) */
+const gchar gfs_module_name[] = "wavewatch";
+const gchar * g_module_check_init (void);
+void          gfs_module_read     (GtsFile * fp, GfsSimulation * sim);
+
+const gchar * g_module_check_init (void)
+{
+  return NULL;
+}
+
+void gfs_module_read (GtsFile * fp, GfsSimulation * sim)
+{
+  g_return_if_fail (fp != NULL);
+  g_return_if_fail (sim != NULL);
+
+  if (!GFS_IS_WAVE (sim)) {
+    gts_file_error (fp, "wavewatch module can only be used with GfsWave");
+    return;
+  }
+
+  GFS_WAVE (sim)->source = wavewatch_source;
+  gfs_domain_get_or_add_variable (GFS_DOMAIN (sim), "Ustar", "Friction velocity");
+  gfs_domain_get_or_add_variable (GFS_DOMAIN (sim), "Fpi",   "Peak-input frequency");
+}
diff --git a/modules/wavewatch/Makefile.am b/modules/wavewatch/Makefile.am
new file mode 100644
index 0000000..7025b6d
--- /dev/null
+++ b/modules/wavewatch/Makefile.am
@@ -0,0 +1,40 @@
+## Process this file with automake to produce Makefile.in
+
+if BUILD_WAVEWATCH
+WAVEWATCH = libwavewatch.a
+CHECKTYPES = checktypes
+endif
+
+noinst_LIBRARIES = $(WAVEWATCH)
+noinst_PROGRAMS = $(CHECKTYPES)
+
+EXTRA_DIST = gfsad3 \
+	w3init222.ftn wavewatch_222.h \
+	wavewatch_312.h \
+	w3init314.ftn wavewatch_314.h \
+	fchecktypes.ftn
+
+checktypes_SOURCES = cchecktypes.c
+checktypes_LDADD = fchecktypes.o
+
+libwavewatch_a_SOURCES =
+
+CLEANFILES = cfortrantypes.h
+
+libwavewatch.a: w3initmd.o
+	rm -f libwavewatch.a
+	$(AR) cru libwavewatch.a `grep WWATCH3_DIR $(HOME)/.wwatch3.env | awk '{print $$2 "/obj/w3*.o"}'` w3initmd.o
+	$(RANLIB) libwavewatch.a
+
+w3initmd.o: $(W3INIT).ftn $(HOME)/.wwatch3.env gfsad3 cfortrantypes.h
+	sh gfsad3 $(W3INIT).ftn
+	mv -f $(W3INIT).o w3initmd.o
+
+fchecktypes.o: fchecktypes.ftn $(HOME)/.wwatch3.env gfsad3
+	sh gfsad3 fchecktypes.ftn
+
+cfortrantypes.h: checktypes
+	./checktypes > cfortrantypes.h
+
+w3init312.ftn: w3init314.ftn
+	cp -f w3init314.ftn w3init312.ftn
diff --git a/modules/wavewatch/Makefile.in b/modules/wavewatch/Makefile.in
new file mode 100644
index 0000000..0ea4028
--- /dev/null
+++ b/modules/wavewatch/Makefile.in
@@ -0,0 +1,543 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = $(am__EXEEXT_1)
+subdir = modules/wavewatch
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libwavewatch_a_AR = $(AR) $(ARFLAGS)
+libwavewatch_a_LIBADD =
+am_libwavewatch_a_OBJECTS =
+libwavewatch_a_OBJECTS = $(am_libwavewatch_a_OBJECTS)
+ at BUILD_WAVEWATCH_TRUE@am__EXEEXT_1 = checktypes$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_checktypes_OBJECTS = cchecktypes.$(OBJEXT)
+checktypes_OBJECTS = $(am_checktypes_OBJECTS)
+checktypes_DEPENDENCIES = fchecktypes.o
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libwavewatch_a_SOURCES) $(checktypes_SOURCES)
+DIST_SOURCES = $(libwavewatch_a_SOURCES) $(checktypes_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+ at BUILD_WAVEWATCH_TRUE@WAVEWATCH = libwavewatch.a
+ at BUILD_WAVEWATCH_TRUE@CHECKTYPES = checktypes
+noinst_LIBRARIES = $(WAVEWATCH)
+EXTRA_DIST = gfsad3 \
+	w3init222.ftn wavewatch_222.h \
+	wavewatch_312.h \
+	w3init314.ftn wavewatch_314.h \
+	fchecktypes.ftn
+
+checktypes_SOURCES = cchecktypes.c
+checktypes_LDADD = fchecktypes.o
+libwavewatch_a_SOURCES = 
+CLEANFILES = cfortrantypes.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/wavewatch/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu modules/wavewatch/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+checktypes$(EXEEXT): $(checktypes_OBJECTS) $(checktypes_DEPENDENCIES) 
+	@rm -f checktypes$(EXEEXT)
+	$(LINK) $(checktypes_OBJECTS) $(checktypes_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cchecktypes.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+	clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am
+
+
+libwavewatch.a: w3initmd.o
+	rm -f libwavewatch.a
+	$(AR) cru libwavewatch.a `grep WWATCH3_DIR $(HOME)/.wwatch3.env | awk '{print $$2 "/obj/w3*.o"}'` w3initmd.o
+	$(RANLIB) libwavewatch.a
+
+w3initmd.o: $(W3INIT).ftn $(HOME)/.wwatch3.env gfsad3 cfortrantypes.h
+	sh gfsad3 $(W3INIT).ftn
+	mv -f $(W3INIT).o w3initmd.o
+
+fchecktypes.o: fchecktypes.ftn $(HOME)/.wwatch3.env gfsad3
+	sh gfsad3 fchecktypes.ftn
+
+cfortrantypes.h: checktypes
+	./checktypes > cfortrantypes.h
+
+w3init312.ftn: w3init314.ftn
+	cp -f w3init314.ftn w3init312.ftn
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/wavewatch/cchecktypes.c b/modules/wavewatch/cchecktypes.c
new file mode 100644
index 0000000..642f3ab
--- /dev/null
+++ b/modules/wavewatch/cchecktypes.c
@@ -0,0 +1,45 @@
+/* Simple checks for compatibility of C and Fortran types */
+
+#include <stdio.h>
+
+extern void check_int_ (void * a, void * b, void * c);
+extern void check_float_ (void * a, void * b, void * c);
+
+int main (int argc, char * argv[])
+{
+  int ia, ib, ic;
+  long long lc, la, lb;
+  float fa, fb, fc;
+  double dc, da, db;
+
+  printf ("/* Automatically generated using 'checktypes' */\n");
+  ia = -123; ib = 875;
+  check_int_ (&ia, &ib, &ic);
+  if (ic == ia*ib)
+    printf ("typedef int INTEGER;\n");
+  else {
+    la = -123; lb = 875;
+    check_int_ (&la, &lb, &lc);
+    if (lc != la*lb) {
+      fprintf (stderr, "checktypes: could not find compatible C and Fortran integers\n");
+      return 1;
+    }
+    printf ("typedef long long INTEGER;\n");
+  }
+
+  fa = -123.; fb = 875.;
+  check_float_ (&fa, &fb, &fc);
+  if (fc == fa*fb)
+    printf ("typedef float REAL;\n");
+  else {
+    da = -123.; db = 875.;
+    check_float_ (&da, &db, &dc);
+    if (dc != da*db) {
+      fprintf (stderr, "checktypes: could not find compatible C and Fortran floats\n");
+      return 1;
+    }
+    printf ("typedef double REAL;\n");
+  }
+
+  return 0;
+}
diff --git a/modules/wavewatch/fchecktypes.ftn b/modules/wavewatch/fchecktypes.ftn
new file mode 100644
index 0000000..674f097
--- /dev/null
+++ b/modules/wavewatch/fchecktypes.ftn
@@ -0,0 +1,9 @@
+! Simple checks for compatibility of C and Fortran types
+SUBROUTINE CHECK_INT ( A, B, C )
+  INTEGER A, B, C
+  C = A*B
+END SUBROUTINE CHECK_INT
+SUBROUTINE CHECK_FLOAT ( A, B, C )
+  REAL A, B, C
+  C = A*B
+END SUBROUTINE CHECK_FLOAT
diff --git a/modules/wavewatch/gfsad3 b/modules/wavewatch/gfsad3
new file mode 100644
index 0000000..92e5060
--- /dev/null
+++ b/modules/wavewatch/gfsad3
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Uses WAVEWATCH III ad3 script to compile an ".ftn" fortran file
+#
+
+if [ "$#" -gt '3' ] || [ "$#" -lt 1 ]; then
+    echo "usage: gfsad3 file.ftn" 1>&2 ; exit 1
+fi
+
+if test -r $HOME/.wwatch3.env; then
+    main_dir=`awk '{if ($1 == "WWATCH3_DIR") print $2;}' < $HOME/.wwatch3.env`
+    tmp_dir=`awk '{if ($1 == "WWATCH3_TMP") print $2;}' < $HOME/.wwatch3.env`
+else
+    echo "gfsad3: Error: Wavewatch environment file '$HOME/.wwatch3.env' not found"
+    exit 1
+fi
+
+if test -f $main_dir/ftn/$1; then
+    echo "gfsad3: Error: file '$main_dir/ftn/$1' already exists"
+    exit 1
+fi
+
+if cp $1 $main_dir/ftn; then :
+else
+    echo "gfsad3: Error: could not copy $1 in '$main_dir/ftn/'"
+    exit 1
+fi
+
+PATH=$PATH:$main_dir/bin
+basename=`basename $1 .ftn`
+ad3 $basename
+rm -f $main_dir/ftn/$1
+
+if test -f $tmp_dir/w3adc.err; then
+    cat $tmp_dir/w3adc.err > /dev/stderr
+    exit 1
+fi
+
+if test -f $tmp_dir/$basename.l; then
+    if awk -v basename=$basename 'BEGIN{FS=":| "; i = 0;}{
+      if ($1 == basename ".f90") i = 1;
+      if (i == 1)
+        print $0;
+    }END{
+      exit (i == 0);
+    }' < $tmp_dir/$basename.l > $tmp_dir/$basename.l.error; then
+	cat $tmp_dir/$basename.l.error > /dev/stderr
+	exit 1
+    fi
+fi
+
+mv -f $main_dir/obj/$basename.o .
diff --git a/modules/wavewatch/w3init222.ftn b/modules/wavewatch/w3init222.ftn
new file mode 100644
index 0000000..a399601
--- /dev/null
+++ b/modules/wavewatch/w3init222.ftn
@@ -0,0 +1,22 @@
+!/ ------------------------------------------------------------------- /
+!
+! Initialisation of Wavewatch III (version 2.22) when used with Gerris
+! (-*-F90-*-)
+!
+!/ ------------------------------------------------------------------- /
+MODULE GFSW3INIT
+  USE W3IOGRMD
+  USE W3TESTMD, ONLY : NAPROC, IAPROC, NAPOUT, NAPERR
+  IMPLICIT NONE
+  PUBLIC
+CONTAINS
+  SUBROUTINE GFSW3_INIT ( )
+    IMPLICIT NONE
+    NAPROC = 1
+    IAPROC = 1
+    NAPOUT = 1
+    NAPERR = 1
+    CALL W3IOGR ( 'READ', 30 )
+    RETURN
+  END SUBROUTINE GFSW3_INIT
+END MODULE GFSW3INIT
diff --git a/modules/wavewatch/w3init314.ftn b/modules/wavewatch/w3init314.ftn
new file mode 100644
index 0000000..fad9529
--- /dev/null
+++ b/modules/wavewatch/w3init314.ftn
@@ -0,0 +1,127 @@
+!/ ------------------------------------------------------------------- /
+!
+! Initialisation of Wavewatch III (version 3.14) when used with Gerris
+! Adapted from ww3_shel.ftn, S. Popinet, 2009       (-*-F90-*-)
+!
+!/ ------------------------------------------------------------------- /
+      MODULE GFSW3INIT
+      USE W3GDATMD
+      USE W3WDATMD, ONLY: TIME, W3NDAT, W3DIMW, W3SETW
+      USE W3ADATMD, ONLY: W3NAUX, W3DIMA, W3SETA
+      USE W3IDATMD
+      USE W3ODATMD, ONLY: W3NOUT, W3SETO
+      USE W3ODATMD, ONLY: NAPROC, IAPROC, NAPOUT, NAPERR,             &
+                          NOGRD, IDOUT, FNMPRE, IOSTYP
+!/
+      USE W3INITMD
+!/
+      IMPLICIT NONE
+!
+!/ ------------------------------------------------------------------- /
+!/ Local parameters
+!/
+      INTEGER             :: NDSO, NDSE, NDST,     &
+                             NDS(13), NTRACE(2),      &
+                             ODAT(30),       &
+                             MPI_COMM = -99, &
+                             IPRT(6)
+      REAL, ALLOCATABLE   :: X(:), Y(:)
+      LOGICAL             :: FLGRD(NOGRD), PRTFRM
+      CHARACTER(LEN=10),                                              &
+              ALLOCATABLE :: PNAMES(:)
+!/
+!/ ------------------------------------------------------------------- /
+!/
+      PUBLIC
+CONTAINS
+      SUBROUTINE GFSW3_INIT ( )
+      IMPLICIT NONE
+!
+!--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+! 0.  Set up data structures
+!
+      CALL W3NMOD ( 1, 6, 6 )
+      CALL W3NDAT (    6, 6 )
+      CALL W3NAUX (    6, 6 )
+      CALL W3NOUT (    6, 6 )
+      CALL W3NINP (    6, 6 )
+!
+      CALL W3SETG ( 1, 6, 6 )
+      CALL W3SETW ( 1, 6, 6 )
+      CALL W3SETA ( 1, 6, 6 )
+      CALL W3SETO ( 1, 6, 6 )
+      CALL W3SETI ( 1, 6, 6 )
+
+! Time is not set
+      TIME(1) = -1
+!
+!/SHRD      NAPROC = 1
+!/SHRD      IAPROC = 1
+!
+!/MPI      IAPROC = IAPROC + 1
+!
+!/NCO/!     IF ( IAPROC .EQ. 1 ) CALL W3TAGB                         &
+!/NCO/!                         ('WAVEFCST',1998,0007,0050,'NP21   ')
+!
+!--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+! 1.  IO set-up
+! 1.a For shell
+!
+      NDSO   =  20
+      NDSE   =  20
+      NDST   =  20
+!
+!/NCO/!
+!/NCO/! Redo according to NCO standard and docblock
+!/NCO/!
+!/NCO      NDSO   =  6
+!/NCO      NDSE   = NDSO
+!/NCO      NDST   = NDSO
+!
+      NAPOUT = 1
+      NAPERR = 1
+!
+! 1.b For WAVEWATCH-III (See W3INIT)
+!
+      NDS( 1) = 20
+      NDS( 2) = 20
+      NDS( 3) = 20
+      NDS( 4) = 20
+      NDS( 5) = 30
+      NDS( 6) = 30
+      NDS( 7) = 31
+      NDS( 8) = 32
+      NDS( 9) = 33
+      NDS(10) = 35
+      NDS(11) = 22
+      NDS(12) = 23
+      NDS(13) = 34
+!
+      NTRACE(1) =  NDS(3)
+      NTRACE(2) =  10
+!
+!/NCO/!
+!/NCO/! Redo according to NCO standard and docblock
+!/NCO/!
+!/NCO      NDS( 1) = 51
+!/NCO      NDS( 2) = NDSO
+!/NCO      NDS( 3) = NDSO
+!/NCO      NDS( 4) = NDSO
+!/NCO      NDS( 5) = 20
+!/NCO      NDS( 6) = 21
+!/NCO      NDS( 7) = 52
+!/NCO      NDS( 8) = 53
+!/NCO      NDS( 9) = 22
+!/NCO      NDS(10) = 71
+!/NCO      NDS(11) = 23
+!/NCO      NDS(12) = 54
+!/NCO      NDS(13) = 55
+!/NCO      NTRACE(1) = NDSO
+!
+! 5.a Wave model
+!
+      CALL W3INIT ( 1, 'ww3', NDS, NTRACE, ODAT, FLGRD, 0, X, Y,   &
+                    PNAMES, IPRT, PRTFRM, -99 )
+      RETURN
+      END SUBROUTINE GFSW3_INIT
+    END MODULE GFSW3INIT
diff --git a/modules/wavewatch/wavewatch_222.h b/modules/wavewatch/wavewatch_222.h
new file mode 100644
index 0000000..dce2d18
--- /dev/null
+++ b/modules/wavewatch/wavewatch_222.h
@@ -0,0 +1,71 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "cfortrantypes.h"
+
+/**
+ * Initialisation of wavewatch
+ */
+extern void GFSW3INIT (void);
+
+/**
+ * imported from w3srcemd.f90:W3SRCE
+ * @SPEC: Spectrum (action) in 1-D form (NK*NTH elements): INPUT/OUTPUT
+ * @SP2D: Spectrum (action) in 2-D form (NK*NTH elements): INPUT/OUTPUT
+ * @ALPHA: Nondimensional 1-D spectrum (NK)                OUTPUT
+ * @WN1: Discrete wavenumbers (NK)                         INPUT
+ * @CG1: Discrete group velocities (NK)                    INPUT
+ * @DEPTH: Depth                                           INPUT
+ * @U10ABS: Wind speed at reference height                 INPUT
+ * @U10DIR: Wind direction at reference height             INPUT
+ * @USTAR: Friction velocity                               INPUT/OUTPUT
+ * @EMEAN: Mean energy                                     OUTPUT (maybe model dependent?)
+ * @FMEAN: Mean frequency                                  OUTPUT (maybe model dependent?)
+ * @WMEAN: Mean wavenumber                                 OUTPUT (maybe model dependent?)
+ * @AMAX: Maximum energy                                   OUTPUT
+ * @FPI: Peak-input frequency                              INPUT/OUTPUT
+ * @CD: Drag coefficient                                   OUTPUT (maybe model dependent?)
+ * @Z0: Roughness length                                   OUTPUT (maybe model dependent?)
+ * @DTDYN: Average dynamic time step                       OUTPUT
+ * @FCUT: Cut-off frequency for tail                       OUTPUT
+ * @DTG: Global time step                                  INPUT
+ * @DTMIN: Minimum (partial) time step                     INPUT
+ * @DTMAX: Maximum (partial) time step                     INPUT
+ */
+extern void W3SRCE (REAL * SPEC,
+		    REAL * SP2D,
+		    REAL * ALPHA,
+		    REAL * WN1, 
+		    REAL * CG1, 
+		    REAL * DEPTH, 
+		    REAL * U10ABS, 
+		    REAL * U10DIR, 
+		    REAL * USTAR,
+		    REAL * EMEAN,
+		    REAL * FMEAN,
+		    REAL * WMEAN,
+		    REAL * AMAX,
+		    REAL * FPI,
+		    REAL * CD,
+		    REAL * Z0,
+		    REAL * DTDYN,
+		    REAL * FCUT,
+		    REAL * DTG,
+		    REAL * DTMIN,
+		    REAL * DTMAX);
diff --git a/modules/wavewatch/wavewatch_312.h b/modules/wavewatch/wavewatch_312.h
new file mode 100644
index 0000000..ec18efe
--- /dev/null
+++ b/modules/wavewatch/wavewatch_312.h
@@ -0,0 +1,70 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "cfortrantypes.h"
+
+/**
+ * Initialisation of wavewatch
+ */
+extern void GFSW3INIT (void);
+
+/**
+ * imported from w3srcemd.f90:W3SRCE
+ * @IX, at IY: Discrete grid point counters (hopefully unused)
+ * @IMOD: Model number (always 1)
+ * @SPEC: Spectrum (action) in 1-D form (NK*NTH elements): INPUT/OUTPUT
+ * @ALPHA: Nondimensional 1-D spectrum (NK)                OUTPUT
+ * @WN1: Discrete wavenumbers (NK)                         INPUT
+ * @CG1: Discrete group velocities (NK)                    INPUT
+ * @DEPTH: Depth                                           INPUT
+ * @U10ABS: Wind speed at reference height                 INPUT
+ * @U10DIR: Wind direction at reference height             INPUT
+ * @USTAR: Friction velocity                               INPUT/OUTPUT
+ * @USTDIR: Friction velocity direction                    OUTPUT (maybe model dependent?)
+ * @EMEAN: Mean energy                                     OUTPUT (maybe model dependent?)
+ * @FMEAN: Mean frequency                                  OUTPUT (maybe model dependent?)
+ * @WMEAN: Mean wavenumber                                 OUTPUT (maybe model dependent?)
+ * @AMAX: Maximum energy                                   OUTPUT
+ * @FPI: Peak-input frequency                              INPUT/OUTPUT
+ * @CD: Drag coefficient                                   OUTPUT (maybe model dependent?)
+ * @Z0: Roughness length                                   OUTPUT (maybe model dependent?)
+ * @DTDYN: Average dynamic time step                       OUTPUT
+ * @FCUT: Cut-off frequency for tail                       OUTPUT
+ * @DTG: Global time step                                  INPUT
+ */
+extern void W3SRCE (INTEGER * IX, INTEGER * IY, INTEGER * IMOD,
+		    REAL * SPEC,
+		    REAL * ALPHA,
+		    REAL * WN1, 
+		    REAL * CG1, 
+		    REAL * DEPTH, 
+		    REAL * U10ABS, 
+		    REAL * U10DIR, 
+		    REAL * USTAR,
+		    REAL * USTDIR,
+		    REAL * EMEAN,
+		    REAL * FMEAN,
+		    REAL * WMEAN,
+		    REAL * AMAX,
+		    REAL * FPI,
+		    REAL * CD,
+		    REAL * Z0,
+		    REAL * DTDYN,
+		    REAL * FCUT,
+		    REAL * DTG);
diff --git a/modules/wavewatch/wavewatch_314.h b/modules/wavewatch/wavewatch_314.h
new file mode 100644
index 0000000..a60f136
--- /dev/null
+++ b/modules/wavewatch/wavewatch_314.h
@@ -0,0 +1,73 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "cfortrantypes.h"
+
+/**
+ * Initialisation of wavewatch
+ */
+extern void GFSW3INIT (void);
+
+/**
+ * imported from w3srcemd.f90:W3SRCE
+ * @IX, at IY: Discrete grid point counters (hopefully unused)
+ * @IMOD: Model number (always 1)
+ * @SPEC: Spectrum (action) in 1-D form (NK*NTH elements): INPUT/OUTPUT
+ * @ALPHA: Nondimensional 1-D spectrum (NK)                OUTPUT
+ * @WN1: Discrete wavenumbers (NK)                         INPUT
+ * @CG1: Discrete group velocities (NK)                    INPUT
+ * @DEPTH: Depth                                           INPUT
+ * @U10ABS: Wind speed at reference height                 INPUT
+ * @U10DIR: Wind direction at reference height             INPUT
+ * @USTAR: Friction velocity                               INPUT/OUTPUT
+ * @USTDIR: Friction velocity direction                    OUTPUT (maybe model dependent?)
+ * @EMEAN: Mean energy                                     OUTPUT (maybe model dependent?)
+ * @FMEAN: Mean frequency                                  OUTPUT (maybe model dependent?)
+ * @WMEAN: Mean wavenumber                                 OUTPUT (maybe model dependent?)
+ * @AMAX: Maximum energy                                   OUTPUT
+ * @FPI: Peak-input frequency                              INPUT/OUTPUT
+ * @CD: Drag coefficient                                   OUTPUT (maybe model dependent?)
+ * @Z0: Roughness length                                   OUTPUT (maybe model dependent?)
+ * @DTDYN: Average dynamic time step                       OUTPUT
+ * @FCUT: Cut-off frequency for tail                       OUTPUT
+ * @DTG: Global time step                                  INPUT
+ */
+extern void W3SRCE (INTEGER * IX, INTEGER * IY, INTEGER * IMOD,
+		    REAL * SPEC,
+		    REAL * ALPHA,
+		    REAL * WN1, 
+		    REAL * CG1, 
+		    REAL * DEPTH, 
+		    REAL * U10ABS, 
+		    REAL * U10DIR, 
+		    REAL * AS,
+		    REAL * USTAR,
+		    REAL * USTDIR,
+		    REAL * CX,
+		    REAL * CY,
+		    REAL * EMEAN,
+		    REAL * FMEAN,
+		    REAL * WMEAN,
+		    REAL * AMAX,
+		    REAL * FPI,
+		    REAL * CD,
+		    REAL * Z0,
+		    REAL * DTDYN,
+		    REAL * FCUT,
+		    REAL * DTG);
diff --git a/modules/xyz2rsurface.c b/modules/xyz2rsurface.c
new file mode 100644
index 0000000..7c1185e
--- /dev/null
+++ b/modules/xyz2rsurface.c
@@ -0,0 +1,111 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+#include "ftt.h"
+#include "rsurface.h"
+
+int main (int argc, char** argv)
+{
+  int c = 0, pagesize = 2048;
+  int verbose = 0;
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"pagesize", required_argument, NULL, 'p'},
+      {"verbose", no_argument, NULL, 'v'},
+      {"help", no_argument, NULL, 'h'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "p:vh",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "p:vh"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'p': /* pagesize */
+      pagesize = atoi (optarg);
+      break;
+    case 'v': /* verbose */
+      verbose = 1;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+	       "Usage: xyz2rsurface [OPTION] BASENAME\n"
+	       "\n"
+	       "Converts the x, y and z coordinates on standard input to an\n"
+	       "R*-tree-indexed database suitable for use with the\n"
+	       "GfsRefineTerrain object of Gerris.\n"
+	       "\n"
+	       "  -p N  --pagesize=N  sets the pagesize in bytes (default is 2048)\n"
+	       "  -v    --verbose     display progress bar\n"
+	       "  -h    --help        display this help and exit\n"
+	       "\n"
+	       "Report bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `xyz2rsurface --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  if (optind >= argc) { /* missing BASENAME */
+    fprintf (stderr, 
+	     "xyz2rsurface: missing BASENAME\n"
+	     "Try `xyz2rsurface --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+  RSurface * rs = r_surface_open (argv[optind], "w", pagesize);
+  if (rs == NULL) {
+    fprintf (stderr, "xyz2rsurface: cannot open files `%s*'\n", argv[optind]);
+    return 1;
+  }
+  double x[3];
+  int count = 0;
+  while (scanf ("%lf %lf %lf", &x[0], &x[1], &x[2]) == 3) {
+    if (!r_surface_insert (rs, x, 0)) {
+      fprintf (stderr, "\nxyz2rsurface: error inserting point #%d (%g,%g,%g)\n",
+	       count, x[0], x[1], x[2]);
+      return 1;
+    }
+    count++;
+    if (verbose && (count % 1000) == 0)
+      fprintf (stderr, "\rxyz2rsurface: %9d points inserted", count);
+  }
+  if (verbose) {
+    fprintf (stderr, "\rxyz2rsurface: %9d points inserted\n", count);
+    fprintf (stderr, "xyz2rsurface: updating...\n");
+  }
+  r_surface_update (rs);
+  r_surface_close (rs);
+
+  return 0.;
+}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..d0ec605
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,159 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = 1.6
+
+AM_CPPFLAGS = -DGFS_MODULES_DIR=\"$(libdir)/gerris\"
+
+INCLUDES = -I$(top_srcdir) -I$(includedir) \
+           -DG_LOG_DOMAIN=\"Gfs\" $(GTS_CFLAGS)
+
+bin_SCRIPTS=gfs-config
+
+gfs-config: gfs-config.in
+gerris2D.pc: gerris2D.pc.in
+gerris2D3.pc: gerris2D3.pc.in
+gerris3D.pc: gerris3D.pc.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gerris2D.pc gerris3D.pc gerris2D3.pc
+pkglib_DATA = m4.awk
+
+lib_LTLIBRARIES = libgfs2D.la libgfs3D.la libgfs2D3.la
+
+BUILT_SOURCES= \
+	gfs-config  \
+	gerris2D.pc \
+	gerris2D3.pc \
+	gerris3D.pc
+
+GFS_HDS = \
+	ftt.h \
+	fluid.h \
+	variable.h \
+	output.h \
+	solid.h \
+	poisson.h \
+	advection.h \
+	boundary.h \
+	mpi_boundary.h \
+	timestep.h \
+	domain.h \
+	init.h \
+	refine.h \
+	event.h \
+	simulation.h \
+	graphic.h \
+	adaptive.h \
+	source.h \
+	tension.h \
+	vof.h \
+	utils.h \
+	ocean.h \
+	wave.h \
+	levelset.h \
+	isocube.h \
+	cartesian.h \
+	surface.h \
+	unstructured.h \
+	map.h \
+	river.h \
+	moving.h \
+	balance.h \
+	metric.h \
+	version.h
+
+pkginclude_HEADERS = \
+	$(GFS_HDS) \
+	spatial.h \
+	function.h
+
+include_HEADERS = \
+	gfs.h \
+	gfsconfig.h
+
+SRC = \
+	ftt.c \
+	fluid.c \
+	variable.c \
+	output.c \
+	solid.c \
+	poisson.c \
+	advection.c \
+	boundary.c \
+	mpi_boundary.c \
+	timestep.c \
+	domain.c \
+	init.c \
+	refine.c \
+	event.c \
+	simulation.c \
+	graphic.c \
+	adaptive.c \
+	source.c \
+	tension.c \
+	vof.c \
+	utils.c \
+	ocean.c \
+	wave.c \
+	levelset.c \
+	myc.h \
+	myc2d.h \
+	cartesian.c \
+	surface.c \
+	unstructured.c \
+	map.c \
+	river.c \
+	moving.c \
+	balance.c \
+	metric.c \
+	$(GFS_HDS)
+
+domain.c: version.h
+
+libgfs3D_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+libgfs3D_la_SOURCES = $(SRC)
+
+libgfs2D_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+libgfs2D_la_SOURCES = $(SRC)
+libgfs2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+
+libgfs2D3_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+libgfs2D3_la_SOURCES = $(SRC)
+libgfs2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+	ftt_internal.c \
+	moving2.c \
+	m4.awk
+
+bin_PROGRAMS = gerris2D gerris3D gerris2D3
+
+gerris2D_SOURCES = gerris.c
+gerris2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gerris2D_LDADD = $(GFS2D_LIBS)
+
+gerris3D_SOURCES = gerris.c
+gerris3D_LDADD = $(GFS3D_LIBS)
+
+gerris2D3_SOURCES = gerris.c
+gerris2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gerris2D3_LDADD = $(GFS2D3_LIBS)
+
+if DARCS_CONTROLLED
+DARCS_VERSION = darcsversion
+else
+DARCS_VERSION = 
+endif
+
+version.h: $(DARCS_VERSION)
+
+darcsversion:
+	sh darcsversion.sh
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..d2d962d
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,1548 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = gerris2D$(EXEEXT) gerris3D$(EXEEXT) gerris2D3$(EXEEXT)
+subdir = src
+DIST_COMMON = $(include_HEADERS) $(pkginclude_HEADERS) \
+	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(srcdir)/gerris2D.pc.in $(srcdir)/gerris2D3.pc.in \
+	$(srcdir)/gerris3D.pc.in $(srcdir)/gfs-config.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gfs-config gerris2D.pc gerris2D3.pc gerris3D.pc
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+	"$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \
+	"$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(includedir)" \
+	"$(DESTDIR)$(pkgincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libgfs2D_la_LIBADD =
+am__objects_1 =
+am__objects_2 = libgfs2D_la-ftt.lo libgfs2D_la-fluid.lo \
+	libgfs2D_la-variable.lo libgfs2D_la-output.lo \
+	libgfs2D_la-solid.lo libgfs2D_la-poisson.lo \
+	libgfs2D_la-advection.lo libgfs2D_la-boundary.lo \
+	libgfs2D_la-mpi_boundary.lo libgfs2D_la-timestep.lo \
+	libgfs2D_la-domain.lo libgfs2D_la-init.lo \
+	libgfs2D_la-refine.lo libgfs2D_la-event.lo \
+	libgfs2D_la-simulation.lo libgfs2D_la-graphic.lo \
+	libgfs2D_la-adaptive.lo libgfs2D_la-source.lo \
+	libgfs2D_la-tension.lo libgfs2D_la-vof.lo libgfs2D_la-utils.lo \
+	libgfs2D_la-ocean.lo libgfs2D_la-wave.lo \
+	libgfs2D_la-levelset.lo libgfs2D_la-cartesian.lo \
+	libgfs2D_la-surface.lo libgfs2D_la-unstructured.lo \
+	libgfs2D_la-map.lo libgfs2D_la-river.lo libgfs2D_la-moving.lo \
+	libgfs2D_la-balance.lo libgfs2D_la-metric.lo $(am__objects_1)
+am_libgfs2D_la_OBJECTS = $(am__objects_2)
+libgfs2D_la_OBJECTS = $(am_libgfs2D_la_OBJECTS)
+libgfs2D_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgfs2D_la_CFLAGS) \
+	$(CFLAGS) $(libgfs2D_la_LDFLAGS) $(LDFLAGS) -o $@
+libgfs2D3_la_LIBADD =
+am__objects_3 = libgfs2D3_la-ftt.lo libgfs2D3_la-fluid.lo \
+	libgfs2D3_la-variable.lo libgfs2D3_la-output.lo \
+	libgfs2D3_la-solid.lo libgfs2D3_la-poisson.lo \
+	libgfs2D3_la-advection.lo libgfs2D3_la-boundary.lo \
+	libgfs2D3_la-mpi_boundary.lo libgfs2D3_la-timestep.lo \
+	libgfs2D3_la-domain.lo libgfs2D3_la-init.lo \
+	libgfs2D3_la-refine.lo libgfs2D3_la-event.lo \
+	libgfs2D3_la-simulation.lo libgfs2D3_la-graphic.lo \
+	libgfs2D3_la-adaptive.lo libgfs2D3_la-source.lo \
+	libgfs2D3_la-tension.lo libgfs2D3_la-vof.lo \
+	libgfs2D3_la-utils.lo libgfs2D3_la-ocean.lo \
+	libgfs2D3_la-wave.lo libgfs2D3_la-levelset.lo \
+	libgfs2D3_la-cartesian.lo libgfs2D3_la-surface.lo \
+	libgfs2D3_la-unstructured.lo libgfs2D3_la-map.lo \
+	libgfs2D3_la-river.lo libgfs2D3_la-moving.lo \
+	libgfs2D3_la-balance.lo libgfs2D3_la-metric.lo \
+	$(am__objects_1)
+am_libgfs2D3_la_OBJECTS = $(am__objects_3)
+libgfs2D3_la_OBJECTS = $(am_libgfs2D3_la_OBJECTS)
+libgfs2D3_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgfs2D3_la_CFLAGS) \
+	$(CFLAGS) $(libgfs2D3_la_LDFLAGS) $(LDFLAGS) -o $@
+libgfs3D_la_LIBADD =
+am__objects_4 = ftt.lo fluid.lo variable.lo output.lo solid.lo \
+	poisson.lo advection.lo boundary.lo mpi_boundary.lo \
+	timestep.lo domain.lo init.lo refine.lo event.lo simulation.lo \
+	graphic.lo adaptive.lo source.lo tension.lo vof.lo utils.lo \
+	ocean.lo wave.lo levelset.lo cartesian.lo surface.lo \
+	unstructured.lo map.lo river.lo moving.lo balance.lo metric.lo \
+	$(am__objects_1)
+am_libgfs3D_la_OBJECTS = $(am__objects_4)
+libgfs3D_la_OBJECTS = $(am_libgfs3D_la_OBJECTS)
+libgfs3D_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libgfs3D_la_LDFLAGS) $(LDFLAGS) -o $@
+PROGRAMS = $(bin_PROGRAMS)
+am_gerris2D_OBJECTS = gerris2D-gerris.$(OBJEXT)
+gerris2D_OBJECTS = $(am_gerris2D_OBJECTS)
+am__DEPENDENCIES_1 =
+gerris2D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gerris2D_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(gerris2D_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_gerris2D3_OBJECTS = gerris2D3-gerris.$(OBJEXT)
+gerris2D3_OBJECTS = $(am_gerris2D3_OBJECTS)
+gerris2D3_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gerris2D3_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gerris2D3_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gerris3D_OBJECTS = gerris.$(OBJEXT)
+gerris3D_OBJECTS = $(am_gerris3D_OBJECTS)
+gerris3D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libgfs2D_la_SOURCES) $(libgfs2D3_la_SOURCES) \
+	$(libgfs3D_la_SOURCES) $(gerris2D_SOURCES) \
+	$(gerris2D3_SOURCES) $(gerris3D_SOURCES)
+DIST_SOURCES = $(libgfs2D_la_SOURCES) $(libgfs2D3_la_SOURCES) \
+	$(libgfs3D_la_SOURCES) $(gerris2D_SOURCES) \
+	$(gerris2D3_SOURCES) $(gerris3D_SOURCES)
+DATA = $(pkgconfig_DATA) $(pkglib_DATA)
+HEADERS = $(include_HEADERS) $(pkginclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+AUTOMAKE_OPTIONS = 1.6
+AM_CPPFLAGS = -DGFS_MODULES_DIR=\"$(libdir)/gerris\"
+INCLUDES = -I$(top_srcdir) -I$(includedir) \
+           -DG_LOG_DOMAIN=\"Gfs\" $(GTS_CFLAGS)
+
+bin_SCRIPTS = gfs-config
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gerris2D.pc gerris3D.pc gerris2D3.pc
+pkglib_DATA = m4.awk
+lib_LTLIBRARIES = libgfs2D.la libgfs3D.la libgfs2D3.la
+BUILT_SOURCES = \
+	gfs-config  \
+	gerris2D.pc \
+	gerris2D3.pc \
+	gerris3D.pc
+
+GFS_HDS = \
+	ftt.h \
+	fluid.h \
+	variable.h \
+	output.h \
+	solid.h \
+	poisson.h \
+	advection.h \
+	boundary.h \
+	mpi_boundary.h \
+	timestep.h \
+	domain.h \
+	init.h \
+	refine.h \
+	event.h \
+	simulation.h \
+	graphic.h \
+	adaptive.h \
+	source.h \
+	tension.h \
+	vof.h \
+	utils.h \
+	ocean.h \
+	wave.h \
+	levelset.h \
+	isocube.h \
+	cartesian.h \
+	surface.h \
+	unstructured.h \
+	map.h \
+	river.h \
+	moving.h \
+	balance.h \
+	metric.h \
+	version.h
+
+pkginclude_HEADERS = \
+	$(GFS_HDS) \
+	spatial.h \
+	function.h
+
+include_HEADERS = \
+	gfs.h \
+	gfsconfig.h
+
+SRC = \
+	ftt.c \
+	fluid.c \
+	variable.c \
+	output.c \
+	solid.c \
+	poisson.c \
+	advection.c \
+	boundary.c \
+	mpi_boundary.c \
+	timestep.c \
+	domain.c \
+	init.c \
+	refine.c \
+	event.c \
+	simulation.c \
+	graphic.c \
+	adaptive.c \
+	source.c \
+	tension.c \
+	vof.c \
+	utils.c \
+	ocean.c \
+	wave.c \
+	levelset.c \
+	myc.h \
+	myc2d.h \
+	cartesian.c \
+	surface.c \
+	unstructured.c \
+	map.c \
+	river.c \
+	moving.c \
+	balance.c \
+	metric.c \
+	$(GFS_HDS)
+
+libgfs3D_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+
+libgfs3D_la_SOURCES = $(SRC)
+libgfs2D_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+
+libgfs2D_la_SOURCES = $(SRC)
+libgfs2D_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+libgfs2D3_la_LDFLAGS = $(NO_UNDEFINED)\
+        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)\
+	-release $(LT_RELEASE) -export-dynamic
+
+libgfs2D3_la_SOURCES = $(SRC)
+libgfs2D3_la_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+CLEANFILES = $(BUILT_SOURCES)
+EXTRA_DIST = \
+	ftt_internal.c \
+	moving2.c \
+	m4.awk
+
+gerris2D_SOURCES = gerris.c
+gerris2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gerris2D_LDADD = $(GFS2D_LIBS)
+gerris3D_SOURCES = gerris.c
+gerris3D_LDADD = $(GFS3D_LIBS)
+gerris2D3_SOURCES = gerris.c
+gerris2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gerris2D3_LDADD = $(GFS2D3_LIBS)
+ at DARCS_CONTROLLED_FALSE@DARCS_VERSION = 
+ at DARCS_CONTROLLED_TRUE@DARCS_VERSION = darcsversion
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+gfs-config: $(top_builddir)/config.status $(srcdir)/gfs-config.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+gerris2D.pc: $(top_builddir)/config.status $(srcdir)/gerris2D.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+gerris2D3.pc: $(top_builddir)/config.status $(srcdir)/gerris2D3.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+gerris3D.pc: $(top_builddir)/config.status $(srcdir)/gerris3D.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libgfs2D.la: $(libgfs2D_la_OBJECTS) $(libgfs2D_la_DEPENDENCIES) 
+	$(libgfs2D_la_LINK) -rpath $(libdir) $(libgfs2D_la_OBJECTS) $(libgfs2D_la_LIBADD) $(LIBS)
+libgfs2D3.la: $(libgfs2D3_la_OBJECTS) $(libgfs2D3_la_DEPENDENCIES) 
+	$(libgfs2D3_la_LINK) -rpath $(libdir) $(libgfs2D3_la_OBJECTS) $(libgfs2D3_la_LIBADD) $(LIBS)
+libgfs3D.la: $(libgfs3D_la_OBJECTS) $(libgfs3D_la_DEPENDENCIES) 
+	$(libgfs3D_la_LINK) -rpath $(libdir) $(libgfs3D_la_OBJECTS) $(libgfs3D_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p || test -f $$p1; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+gerris2D$(EXEEXT): $(gerris2D_OBJECTS) $(gerris2D_DEPENDENCIES) 
+	@rm -f gerris2D$(EXEEXT)
+	$(gerris2D_LINK) $(gerris2D_OBJECTS) $(gerris2D_LDADD) $(LIBS)
+gerris2D3$(EXEEXT): $(gerris2D3_OBJECTS) $(gerris2D3_DEPENDENCIES) 
+	@rm -f gerris2D3$(EXEEXT)
+	$(gerris2D3_LINK) $(gerris2D3_OBJECTS) $(gerris2D3_LDADD) $(LIBS)
+gerris3D$(EXEEXT): $(gerris3D_OBJECTS) $(gerris3D_DEPENDENCIES) 
+	@rm -f gerris3D$(EXEEXT)
+	$(LINK) $(gerris3D_OBJECTS) $(gerris3D_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/adaptive.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/advection.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/balance.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cartesian.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/domain.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/event.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fluid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ftt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gerris.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gerris2D-gerris.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gerris2D3-gerris.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/graphic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/init.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/levelset.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-adaptive.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-advection.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-balance.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-cartesian.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-domain.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-event.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-fluid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-ftt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-graphic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-init.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-levelset.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-metric.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-moving.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-mpi_boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-ocean.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-output.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-poisson.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-refine.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-river.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-simulation.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-solid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-source.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-surface.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-tension.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-timestep.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-unstructured.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-utils.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-variable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-vof.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D3_la-wave.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-adaptive.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-advection.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-balance.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-cartesian.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-domain.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-event.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-fluid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-ftt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-graphic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-init.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-levelset.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-metric.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-moving.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-mpi_boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-ocean.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-output.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-poisson.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-refine.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-river.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-simulation.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-solid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-source.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-surface.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-tension.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-timestep.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-unstructured.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-utils.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-variable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-vof.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libgfs2D_la-wave.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/metric.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/moving.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mpi_boundary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocean.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/output.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/poisson.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/refine.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/river.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/simulation.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/solid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/source.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/surface.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tension.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/timestep.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/unstructured.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/utils.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/variable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/vof.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wave.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+libgfs2D_la-ftt.lo: ftt.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-ftt.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-ftt.Tpo -c -o libgfs2D_la-ftt.lo `test -f 'ftt.c' || echo '$(srcdir)/'`ftt.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-ftt.Tpo $(DEPDIR)/libgfs2D_la-ftt.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ftt.c' object='libgfs2D_la-ftt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-ftt.lo `test -f 'ftt.c' || echo '$(srcdir)/'`ftt.c
+
+libgfs2D_la-fluid.lo: fluid.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-fluid.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-fluid.Tpo -c -o libgfs2D_la-fluid.lo `test -f 'fluid.c' || echo '$(srcdir)/'`fluid.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-fluid.Tpo $(DEPDIR)/libgfs2D_la-fluid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fluid.c' object='libgfs2D_la-fluid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-fluid.lo `test -f 'fluid.c' || echo '$(srcdir)/'`fluid.c
+
+libgfs2D_la-variable.lo: variable.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-variable.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-variable.Tpo -c -o libgfs2D_la-variable.lo `test -f 'variable.c' || echo '$(srcdir)/'`variable.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-variable.Tpo $(DEPDIR)/libgfs2D_la-variable.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='variable.c' object='libgfs2D_la-variable.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-variable.lo `test -f 'variable.c' || echo '$(srcdir)/'`variable.c
+
+libgfs2D_la-output.lo: output.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-output.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-output.Tpo -c -o libgfs2D_la-output.lo `test -f 'output.c' || echo '$(srcdir)/'`output.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-output.Tpo $(DEPDIR)/libgfs2D_la-output.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='output.c' object='libgfs2D_la-output.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-output.lo `test -f 'output.c' || echo '$(srcdir)/'`output.c
+
+libgfs2D_la-solid.lo: solid.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-solid.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-solid.Tpo -c -o libgfs2D_la-solid.lo `test -f 'solid.c' || echo '$(srcdir)/'`solid.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-solid.Tpo $(DEPDIR)/libgfs2D_la-solid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='solid.c' object='libgfs2D_la-solid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-solid.lo `test -f 'solid.c' || echo '$(srcdir)/'`solid.c
+
+libgfs2D_la-poisson.lo: poisson.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-poisson.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-poisson.Tpo -c -o libgfs2D_la-poisson.lo `test -f 'poisson.c' || echo '$(srcdir)/'`poisson.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-poisson.Tpo $(DEPDIR)/libgfs2D_la-poisson.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='poisson.c' object='libgfs2D_la-poisson.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-poisson.lo `test -f 'poisson.c' || echo '$(srcdir)/'`poisson.c
+
+libgfs2D_la-advection.lo: advection.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-advection.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-advection.Tpo -c -o libgfs2D_la-advection.lo `test -f 'advection.c' || echo '$(srcdir)/'`advection.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-advection.Tpo $(DEPDIR)/libgfs2D_la-advection.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='advection.c' object='libgfs2D_la-advection.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-advection.lo `test -f 'advection.c' || echo '$(srcdir)/'`advection.c
+
+libgfs2D_la-boundary.lo: boundary.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-boundary.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-boundary.Tpo -c -o libgfs2D_la-boundary.lo `test -f 'boundary.c' || echo '$(srcdir)/'`boundary.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-boundary.Tpo $(DEPDIR)/libgfs2D_la-boundary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boundary.c' object='libgfs2D_la-boundary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-boundary.lo `test -f 'boundary.c' || echo '$(srcdir)/'`boundary.c
+
+libgfs2D_la-mpi_boundary.lo: mpi_boundary.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-mpi_boundary.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-mpi_boundary.Tpo -c -o libgfs2D_la-mpi_boundary.lo `test -f 'mpi_boundary.c' || echo '$(srcdir)/'`mpi_boundary.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-mpi_boundary.Tpo $(DEPDIR)/libgfs2D_la-mpi_boundary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mpi_boundary.c' object='libgfs2D_la-mpi_boundary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-mpi_boundary.lo `test -f 'mpi_boundary.c' || echo '$(srcdir)/'`mpi_boundary.c
+
+libgfs2D_la-timestep.lo: timestep.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-timestep.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-timestep.Tpo -c -o libgfs2D_la-timestep.lo `test -f 'timestep.c' || echo '$(srcdir)/'`timestep.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-timestep.Tpo $(DEPDIR)/libgfs2D_la-timestep.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='timestep.c' object='libgfs2D_la-timestep.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-timestep.lo `test -f 'timestep.c' || echo '$(srcdir)/'`timestep.c
+
+libgfs2D_la-domain.lo: domain.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-domain.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-domain.Tpo -c -o libgfs2D_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-domain.Tpo $(DEPDIR)/libgfs2D_la-domain.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='domain.c' object='libgfs2D_la-domain.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
+
+libgfs2D_la-init.lo: init.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-init.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-init.Tpo -c -o libgfs2D_la-init.lo `test -f 'init.c' || echo '$(srcdir)/'`init.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-init.Tpo $(DEPDIR)/libgfs2D_la-init.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='init.c' object='libgfs2D_la-init.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-init.lo `test -f 'init.c' || echo '$(srcdir)/'`init.c
+
+libgfs2D_la-refine.lo: refine.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-refine.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-refine.Tpo -c -o libgfs2D_la-refine.lo `test -f 'refine.c' || echo '$(srcdir)/'`refine.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-refine.Tpo $(DEPDIR)/libgfs2D_la-refine.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='refine.c' object='libgfs2D_la-refine.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-refine.lo `test -f 'refine.c' || echo '$(srcdir)/'`refine.c
+
+libgfs2D_la-event.lo: event.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-event.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-event.Tpo -c -o libgfs2D_la-event.lo `test -f 'event.c' || echo '$(srcdir)/'`event.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-event.Tpo $(DEPDIR)/libgfs2D_la-event.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='event.c' object='libgfs2D_la-event.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-event.lo `test -f 'event.c' || echo '$(srcdir)/'`event.c
+
+libgfs2D_la-simulation.lo: simulation.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-simulation.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-simulation.Tpo -c -o libgfs2D_la-simulation.lo `test -f 'simulation.c' || echo '$(srcdir)/'`simulation.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-simulation.Tpo $(DEPDIR)/libgfs2D_la-simulation.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='simulation.c' object='libgfs2D_la-simulation.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-simulation.lo `test -f 'simulation.c' || echo '$(srcdir)/'`simulation.c
+
+libgfs2D_la-graphic.lo: graphic.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-graphic.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-graphic.Tpo -c -o libgfs2D_la-graphic.lo `test -f 'graphic.c' || echo '$(srcdir)/'`graphic.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-graphic.Tpo $(DEPDIR)/libgfs2D_la-graphic.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='graphic.c' object='libgfs2D_la-graphic.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-graphic.lo `test -f 'graphic.c' || echo '$(srcdir)/'`graphic.c
+
+libgfs2D_la-adaptive.lo: adaptive.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-adaptive.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-adaptive.Tpo -c -o libgfs2D_la-adaptive.lo `test -f 'adaptive.c' || echo '$(srcdir)/'`adaptive.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-adaptive.Tpo $(DEPDIR)/libgfs2D_la-adaptive.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='adaptive.c' object='libgfs2D_la-adaptive.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-adaptive.lo `test -f 'adaptive.c' || echo '$(srcdir)/'`adaptive.c
+
+libgfs2D_la-source.lo: source.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-source.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-source.Tpo -c -o libgfs2D_la-source.lo `test -f 'source.c' || echo '$(srcdir)/'`source.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-source.Tpo $(DEPDIR)/libgfs2D_la-source.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='source.c' object='libgfs2D_la-source.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-source.lo `test -f 'source.c' || echo '$(srcdir)/'`source.c
+
+libgfs2D_la-tension.lo: tension.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-tension.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-tension.Tpo -c -o libgfs2D_la-tension.lo `test -f 'tension.c' || echo '$(srcdir)/'`tension.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-tension.Tpo $(DEPDIR)/libgfs2D_la-tension.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tension.c' object='libgfs2D_la-tension.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-tension.lo `test -f 'tension.c' || echo '$(srcdir)/'`tension.c
+
+libgfs2D_la-vof.lo: vof.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-vof.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-vof.Tpo -c -o libgfs2D_la-vof.lo `test -f 'vof.c' || echo '$(srcdir)/'`vof.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-vof.Tpo $(DEPDIR)/libgfs2D_la-vof.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='vof.c' object='libgfs2D_la-vof.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-vof.lo `test -f 'vof.c' || echo '$(srcdir)/'`vof.c
+
+libgfs2D_la-utils.lo: utils.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-utils.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-utils.Tpo -c -o libgfs2D_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-utils.Tpo $(DEPDIR)/libgfs2D_la-utils.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='utils.c' object='libgfs2D_la-utils.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+
+libgfs2D_la-ocean.lo: ocean.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-ocean.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-ocean.Tpo -c -o libgfs2D_la-ocean.lo `test -f 'ocean.c' || echo '$(srcdir)/'`ocean.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-ocean.Tpo $(DEPDIR)/libgfs2D_la-ocean.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ocean.c' object='libgfs2D_la-ocean.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-ocean.lo `test -f 'ocean.c' || echo '$(srcdir)/'`ocean.c
+
+libgfs2D_la-wave.lo: wave.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-wave.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-wave.Tpo -c -o libgfs2D_la-wave.lo `test -f 'wave.c' || echo '$(srcdir)/'`wave.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-wave.Tpo $(DEPDIR)/libgfs2D_la-wave.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='wave.c' object='libgfs2D_la-wave.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-wave.lo `test -f 'wave.c' || echo '$(srcdir)/'`wave.c
+
+libgfs2D_la-levelset.lo: levelset.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-levelset.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-levelset.Tpo -c -o libgfs2D_la-levelset.lo `test -f 'levelset.c' || echo '$(srcdir)/'`levelset.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-levelset.Tpo $(DEPDIR)/libgfs2D_la-levelset.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='levelset.c' object='libgfs2D_la-levelset.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-levelset.lo `test -f 'levelset.c' || echo '$(srcdir)/'`levelset.c
+
+libgfs2D_la-cartesian.lo: cartesian.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-cartesian.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-cartesian.Tpo -c -o libgfs2D_la-cartesian.lo `test -f 'cartesian.c' || echo '$(srcdir)/'`cartesian.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-cartesian.Tpo $(DEPDIR)/libgfs2D_la-cartesian.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cartesian.c' object='libgfs2D_la-cartesian.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-cartesian.lo `test -f 'cartesian.c' || echo '$(srcdir)/'`cartesian.c
+
+libgfs2D_la-surface.lo: surface.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-surface.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-surface.Tpo -c -o libgfs2D_la-surface.lo `test -f 'surface.c' || echo '$(srcdir)/'`surface.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-surface.Tpo $(DEPDIR)/libgfs2D_la-surface.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='surface.c' object='libgfs2D_la-surface.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-surface.lo `test -f 'surface.c' || echo '$(srcdir)/'`surface.c
+
+libgfs2D_la-unstructured.lo: unstructured.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-unstructured.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-unstructured.Tpo -c -o libgfs2D_la-unstructured.lo `test -f 'unstructured.c' || echo '$(srcdir)/'`unstructured.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-unstructured.Tpo $(DEPDIR)/libgfs2D_la-unstructured.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='unstructured.c' object='libgfs2D_la-unstructured.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-unstructured.lo `test -f 'unstructured.c' || echo '$(srcdir)/'`unstructured.c
+
+libgfs2D_la-map.lo: map.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-map.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-map.Tpo -c -o libgfs2D_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-map.Tpo $(DEPDIR)/libgfs2D_la-map.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='map.c' object='libgfs2D_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+
+libgfs2D_la-river.lo: river.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-river.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-river.Tpo -c -o libgfs2D_la-river.lo `test -f 'river.c' || echo '$(srcdir)/'`river.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-river.Tpo $(DEPDIR)/libgfs2D_la-river.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='river.c' object='libgfs2D_la-river.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-river.lo `test -f 'river.c' || echo '$(srcdir)/'`river.c
+
+libgfs2D_la-moving.lo: moving.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-moving.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-moving.Tpo -c -o libgfs2D_la-moving.lo `test -f 'moving.c' || echo '$(srcdir)/'`moving.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-moving.Tpo $(DEPDIR)/libgfs2D_la-moving.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='moving.c' object='libgfs2D_la-moving.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-moving.lo `test -f 'moving.c' || echo '$(srcdir)/'`moving.c
+
+libgfs2D_la-balance.lo: balance.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-balance.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-balance.Tpo -c -o libgfs2D_la-balance.lo `test -f 'balance.c' || echo '$(srcdir)/'`balance.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-balance.Tpo $(DEPDIR)/libgfs2D_la-balance.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='balance.c' object='libgfs2D_la-balance.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-balance.lo `test -f 'balance.c' || echo '$(srcdir)/'`balance.c
+
+libgfs2D_la-metric.lo: metric.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -MT libgfs2D_la-metric.lo -MD -MP -MF $(DEPDIR)/libgfs2D_la-metric.Tpo -c -o libgfs2D_la-metric.lo `test -f 'metric.c' || echo '$(srcdir)/'`metric.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D_la-metric.Tpo $(DEPDIR)/libgfs2D_la-metric.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='metric.c' object='libgfs2D_la-metric.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D_la_CFLAGS) $(CFLAGS) -c -o libgfs2D_la-metric.lo `test -f 'metric.c' || echo '$(srcdir)/'`metric.c
+
+libgfs2D3_la-ftt.lo: ftt.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-ftt.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-ftt.Tpo -c -o libgfs2D3_la-ftt.lo `test -f 'ftt.c' || echo '$(srcdir)/'`ftt.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-ftt.Tpo $(DEPDIR)/libgfs2D3_la-ftt.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ftt.c' object='libgfs2D3_la-ftt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-ftt.lo `test -f 'ftt.c' || echo '$(srcdir)/'`ftt.c
+
+libgfs2D3_la-fluid.lo: fluid.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-fluid.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-fluid.Tpo -c -o libgfs2D3_la-fluid.lo `test -f 'fluid.c' || echo '$(srcdir)/'`fluid.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-fluid.Tpo $(DEPDIR)/libgfs2D3_la-fluid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fluid.c' object='libgfs2D3_la-fluid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-fluid.lo `test -f 'fluid.c' || echo '$(srcdir)/'`fluid.c
+
+libgfs2D3_la-variable.lo: variable.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-variable.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-variable.Tpo -c -o libgfs2D3_la-variable.lo `test -f 'variable.c' || echo '$(srcdir)/'`variable.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-variable.Tpo $(DEPDIR)/libgfs2D3_la-variable.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='variable.c' object='libgfs2D3_la-variable.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-variable.lo `test -f 'variable.c' || echo '$(srcdir)/'`variable.c
+
+libgfs2D3_la-output.lo: output.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-output.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-output.Tpo -c -o libgfs2D3_la-output.lo `test -f 'output.c' || echo '$(srcdir)/'`output.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-output.Tpo $(DEPDIR)/libgfs2D3_la-output.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='output.c' object='libgfs2D3_la-output.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-output.lo `test -f 'output.c' || echo '$(srcdir)/'`output.c
+
+libgfs2D3_la-solid.lo: solid.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-solid.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-solid.Tpo -c -o libgfs2D3_la-solid.lo `test -f 'solid.c' || echo '$(srcdir)/'`solid.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-solid.Tpo $(DEPDIR)/libgfs2D3_la-solid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='solid.c' object='libgfs2D3_la-solid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-solid.lo `test -f 'solid.c' || echo '$(srcdir)/'`solid.c
+
+libgfs2D3_la-poisson.lo: poisson.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-poisson.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-poisson.Tpo -c -o libgfs2D3_la-poisson.lo `test -f 'poisson.c' || echo '$(srcdir)/'`poisson.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-poisson.Tpo $(DEPDIR)/libgfs2D3_la-poisson.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='poisson.c' object='libgfs2D3_la-poisson.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-poisson.lo `test -f 'poisson.c' || echo '$(srcdir)/'`poisson.c
+
+libgfs2D3_la-advection.lo: advection.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-advection.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-advection.Tpo -c -o libgfs2D3_la-advection.lo `test -f 'advection.c' || echo '$(srcdir)/'`advection.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-advection.Tpo $(DEPDIR)/libgfs2D3_la-advection.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='advection.c' object='libgfs2D3_la-advection.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-advection.lo `test -f 'advection.c' || echo '$(srcdir)/'`advection.c
+
+libgfs2D3_la-boundary.lo: boundary.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-boundary.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-boundary.Tpo -c -o libgfs2D3_la-boundary.lo `test -f 'boundary.c' || echo '$(srcdir)/'`boundary.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-boundary.Tpo $(DEPDIR)/libgfs2D3_la-boundary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boundary.c' object='libgfs2D3_la-boundary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-boundary.lo `test -f 'boundary.c' || echo '$(srcdir)/'`boundary.c
+
+libgfs2D3_la-mpi_boundary.lo: mpi_boundary.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-mpi_boundary.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-mpi_boundary.Tpo -c -o libgfs2D3_la-mpi_boundary.lo `test -f 'mpi_boundary.c' || echo '$(srcdir)/'`mpi_boundary.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-mpi_boundary.Tpo $(DEPDIR)/libgfs2D3_la-mpi_boundary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='mpi_boundary.c' object='libgfs2D3_la-mpi_boundary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-mpi_boundary.lo `test -f 'mpi_boundary.c' || echo '$(srcdir)/'`mpi_boundary.c
+
+libgfs2D3_la-timestep.lo: timestep.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-timestep.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-timestep.Tpo -c -o libgfs2D3_la-timestep.lo `test -f 'timestep.c' || echo '$(srcdir)/'`timestep.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-timestep.Tpo $(DEPDIR)/libgfs2D3_la-timestep.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='timestep.c' object='libgfs2D3_la-timestep.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-timestep.lo `test -f 'timestep.c' || echo '$(srcdir)/'`timestep.c
+
+libgfs2D3_la-domain.lo: domain.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-domain.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-domain.Tpo -c -o libgfs2D3_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-domain.Tpo $(DEPDIR)/libgfs2D3_la-domain.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='domain.c' object='libgfs2D3_la-domain.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
+
+libgfs2D3_la-init.lo: init.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-init.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-init.Tpo -c -o libgfs2D3_la-init.lo `test -f 'init.c' || echo '$(srcdir)/'`init.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-init.Tpo $(DEPDIR)/libgfs2D3_la-init.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='init.c' object='libgfs2D3_la-init.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-init.lo `test -f 'init.c' || echo '$(srcdir)/'`init.c
+
+libgfs2D3_la-refine.lo: refine.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-refine.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-refine.Tpo -c -o libgfs2D3_la-refine.lo `test -f 'refine.c' || echo '$(srcdir)/'`refine.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-refine.Tpo $(DEPDIR)/libgfs2D3_la-refine.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='refine.c' object='libgfs2D3_la-refine.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-refine.lo `test -f 'refine.c' || echo '$(srcdir)/'`refine.c
+
+libgfs2D3_la-event.lo: event.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-event.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-event.Tpo -c -o libgfs2D3_la-event.lo `test -f 'event.c' || echo '$(srcdir)/'`event.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-event.Tpo $(DEPDIR)/libgfs2D3_la-event.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='event.c' object='libgfs2D3_la-event.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-event.lo `test -f 'event.c' || echo '$(srcdir)/'`event.c
+
+libgfs2D3_la-simulation.lo: simulation.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-simulation.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-simulation.Tpo -c -o libgfs2D3_la-simulation.lo `test -f 'simulation.c' || echo '$(srcdir)/'`simulation.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-simulation.Tpo $(DEPDIR)/libgfs2D3_la-simulation.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='simulation.c' object='libgfs2D3_la-simulation.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-simulation.lo `test -f 'simulation.c' || echo '$(srcdir)/'`simulation.c
+
+libgfs2D3_la-graphic.lo: graphic.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-graphic.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-graphic.Tpo -c -o libgfs2D3_la-graphic.lo `test -f 'graphic.c' || echo '$(srcdir)/'`graphic.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-graphic.Tpo $(DEPDIR)/libgfs2D3_la-graphic.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='graphic.c' object='libgfs2D3_la-graphic.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-graphic.lo `test -f 'graphic.c' || echo '$(srcdir)/'`graphic.c
+
+libgfs2D3_la-adaptive.lo: adaptive.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-adaptive.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-adaptive.Tpo -c -o libgfs2D3_la-adaptive.lo `test -f 'adaptive.c' || echo '$(srcdir)/'`adaptive.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-adaptive.Tpo $(DEPDIR)/libgfs2D3_la-adaptive.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='adaptive.c' object='libgfs2D3_la-adaptive.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-adaptive.lo `test -f 'adaptive.c' || echo '$(srcdir)/'`adaptive.c
+
+libgfs2D3_la-source.lo: source.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-source.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-source.Tpo -c -o libgfs2D3_la-source.lo `test -f 'source.c' || echo '$(srcdir)/'`source.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-source.Tpo $(DEPDIR)/libgfs2D3_la-source.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='source.c' object='libgfs2D3_la-source.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-source.lo `test -f 'source.c' || echo '$(srcdir)/'`source.c
+
+libgfs2D3_la-tension.lo: tension.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-tension.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-tension.Tpo -c -o libgfs2D3_la-tension.lo `test -f 'tension.c' || echo '$(srcdir)/'`tension.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-tension.Tpo $(DEPDIR)/libgfs2D3_la-tension.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tension.c' object='libgfs2D3_la-tension.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-tension.lo `test -f 'tension.c' || echo '$(srcdir)/'`tension.c
+
+libgfs2D3_la-vof.lo: vof.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-vof.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-vof.Tpo -c -o libgfs2D3_la-vof.lo `test -f 'vof.c' || echo '$(srcdir)/'`vof.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-vof.Tpo $(DEPDIR)/libgfs2D3_la-vof.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='vof.c' object='libgfs2D3_la-vof.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-vof.lo `test -f 'vof.c' || echo '$(srcdir)/'`vof.c
+
+libgfs2D3_la-utils.lo: utils.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-utils.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-utils.Tpo -c -o libgfs2D3_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-utils.Tpo $(DEPDIR)/libgfs2D3_la-utils.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='utils.c' object='libgfs2D3_la-utils.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+
+libgfs2D3_la-ocean.lo: ocean.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-ocean.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-ocean.Tpo -c -o libgfs2D3_la-ocean.lo `test -f 'ocean.c' || echo '$(srcdir)/'`ocean.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-ocean.Tpo $(DEPDIR)/libgfs2D3_la-ocean.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ocean.c' object='libgfs2D3_la-ocean.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-ocean.lo `test -f 'ocean.c' || echo '$(srcdir)/'`ocean.c
+
+libgfs2D3_la-wave.lo: wave.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-wave.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-wave.Tpo -c -o libgfs2D3_la-wave.lo `test -f 'wave.c' || echo '$(srcdir)/'`wave.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-wave.Tpo $(DEPDIR)/libgfs2D3_la-wave.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='wave.c' object='libgfs2D3_la-wave.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-wave.lo `test -f 'wave.c' || echo '$(srcdir)/'`wave.c
+
+libgfs2D3_la-levelset.lo: levelset.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-levelset.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-levelset.Tpo -c -o libgfs2D3_la-levelset.lo `test -f 'levelset.c' || echo '$(srcdir)/'`levelset.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-levelset.Tpo $(DEPDIR)/libgfs2D3_la-levelset.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='levelset.c' object='libgfs2D3_la-levelset.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-levelset.lo `test -f 'levelset.c' || echo '$(srcdir)/'`levelset.c
+
+libgfs2D3_la-cartesian.lo: cartesian.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-cartesian.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-cartesian.Tpo -c -o libgfs2D3_la-cartesian.lo `test -f 'cartesian.c' || echo '$(srcdir)/'`cartesian.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-cartesian.Tpo $(DEPDIR)/libgfs2D3_la-cartesian.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cartesian.c' object='libgfs2D3_la-cartesian.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-cartesian.lo `test -f 'cartesian.c' || echo '$(srcdir)/'`cartesian.c
+
+libgfs2D3_la-surface.lo: surface.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-surface.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-surface.Tpo -c -o libgfs2D3_la-surface.lo `test -f 'surface.c' || echo '$(srcdir)/'`surface.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-surface.Tpo $(DEPDIR)/libgfs2D3_la-surface.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='surface.c' object='libgfs2D3_la-surface.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-surface.lo `test -f 'surface.c' || echo '$(srcdir)/'`surface.c
+
+libgfs2D3_la-unstructured.lo: unstructured.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-unstructured.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-unstructured.Tpo -c -o libgfs2D3_la-unstructured.lo `test -f 'unstructured.c' || echo '$(srcdir)/'`unstructured.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-unstructured.Tpo $(DEPDIR)/libgfs2D3_la-unstructured.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='unstructured.c' object='libgfs2D3_la-unstructured.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-unstructured.lo `test -f 'unstructured.c' || echo '$(srcdir)/'`unstructured.c
+
+libgfs2D3_la-map.lo: map.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-map.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-map.Tpo -c -o libgfs2D3_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-map.Tpo $(DEPDIR)/libgfs2D3_la-map.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='map.c' object='libgfs2D3_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-map.lo `test -f 'map.c' || echo '$(srcdir)/'`map.c
+
+libgfs2D3_la-river.lo: river.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-river.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-river.Tpo -c -o libgfs2D3_la-river.lo `test -f 'river.c' || echo '$(srcdir)/'`river.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-river.Tpo $(DEPDIR)/libgfs2D3_la-river.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='river.c' object='libgfs2D3_la-river.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-river.lo `test -f 'river.c' || echo '$(srcdir)/'`river.c
+
+libgfs2D3_la-moving.lo: moving.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-moving.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-moving.Tpo -c -o libgfs2D3_la-moving.lo `test -f 'moving.c' || echo '$(srcdir)/'`moving.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-moving.Tpo $(DEPDIR)/libgfs2D3_la-moving.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='moving.c' object='libgfs2D3_la-moving.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-moving.lo `test -f 'moving.c' || echo '$(srcdir)/'`moving.c
+
+libgfs2D3_la-balance.lo: balance.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-balance.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-balance.Tpo -c -o libgfs2D3_la-balance.lo `test -f 'balance.c' || echo '$(srcdir)/'`balance.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-balance.Tpo $(DEPDIR)/libgfs2D3_la-balance.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='balance.c' object='libgfs2D3_la-balance.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-balance.lo `test -f 'balance.c' || echo '$(srcdir)/'`balance.c
+
+libgfs2D3_la-metric.lo: metric.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -MT libgfs2D3_la-metric.lo -MD -MP -MF $(DEPDIR)/libgfs2D3_la-metric.Tpo -c -o libgfs2D3_la-metric.lo `test -f 'metric.c' || echo '$(srcdir)/'`metric.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libgfs2D3_la-metric.Tpo $(DEPDIR)/libgfs2D3_la-metric.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='metric.c' object='libgfs2D3_la-metric.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgfs2D3_la_CFLAGS) $(CFLAGS) -c -o libgfs2D3_la-metric.lo `test -f 'metric.c' || echo '$(srcdir)/'`metric.c
+
+gerris2D-gerris.o: gerris.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D_CFLAGS) $(CFLAGS) -MT gerris2D-gerris.o -MD -MP -MF $(DEPDIR)/gerris2D-gerris.Tpo -c -o gerris2D-gerris.o `test -f 'gerris.c' || echo '$(srcdir)/'`gerris.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gerris2D-gerris.Tpo $(DEPDIR)/gerris2D-gerris.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gerris.c' object='gerris2D-gerris.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D_CFLAGS) $(CFLAGS) -c -o gerris2D-gerris.o `test -f 'gerris.c' || echo '$(srcdir)/'`gerris.c
+
+gerris2D-gerris.obj: gerris.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D_CFLAGS) $(CFLAGS) -MT gerris2D-gerris.obj -MD -MP -MF $(DEPDIR)/gerris2D-gerris.Tpo -c -o gerris2D-gerris.obj `if test -f 'gerris.c'; then $(CYGPATH_W) 'gerris.c'; else $(CYGPATH_W) '$(srcdir)/gerris.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gerris2D-gerris.Tpo $(DEPDIR)/gerris2D-gerris.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gerris.c' object='gerris2D-gerris.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D_CFLAGS) $(CFLAGS) -c -o gerris2D-gerris.obj `if test -f 'gerris.c'; then $(CYGPATH_W) 'gerris.c'; else $(CYGPATH_W) '$(srcdir)/gerris.c'; fi`
+
+gerris2D3-gerris.o: gerris.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D3_CFLAGS) $(CFLAGS) -MT gerris2D3-gerris.o -MD -MP -MF $(DEPDIR)/gerris2D3-gerris.Tpo -c -o gerris2D3-gerris.o `test -f 'gerris.c' || echo '$(srcdir)/'`gerris.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gerris2D3-gerris.Tpo $(DEPDIR)/gerris2D3-gerris.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gerris.c' object='gerris2D3-gerris.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D3_CFLAGS) $(CFLAGS) -c -o gerris2D3-gerris.o `test -f 'gerris.c' || echo '$(srcdir)/'`gerris.c
+
+gerris2D3-gerris.obj: gerris.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D3_CFLAGS) $(CFLAGS) -MT gerris2D3-gerris.obj -MD -MP -MF $(DEPDIR)/gerris2D3-gerris.Tpo -c -o gerris2D3-gerris.obj `if test -f 'gerris.c'; then $(CYGPATH_W) 'gerris.c'; else $(CYGPATH_W) '$(srcdir)/gerris.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gerris2D3-gerris.Tpo $(DEPDIR)/gerris2D3-gerris.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gerris.c' object='gerris2D3-gerris.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gerris2D3_CFLAGS) $(CFLAGS) -c -o gerris2D3-gerris.obj `if test -f 'gerris.c'; then $(CYGPATH_W) 'gerris.c'; else $(CYGPATH_W) '$(srcdir)/gerris.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
+install-pkglibDATA: $(pkglib_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkglibdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkglibdir)" || exit $$?; \
+	done
+
+uninstall-pkglibDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_DATA)'; test -n "$(pkglibdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files
+install-includeHEADERS: $(include_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+	done
+
+uninstall-includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(includedir)" && rm -f $$files
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+		$(HEADERS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+	clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS install-pkgconfigDATA \
+	install-pkgincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+	install-libLTLIBRARIES install-pkglibDATA
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+	uninstall-includeHEADERS uninstall-libLTLIBRARIES \
+	uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS \
+	uninstall-pkglibDATA
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic clean-libLTLIBRARIES clean-libtool ctags \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-binSCRIPTS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-includeHEADERS install-info \
+	install-info-am install-libLTLIBRARIES install-man install-pdf \
+	install-pdf-am install-pkgconfigDATA install-pkgincludeHEADERS \
+	install-pkglibDATA install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-binSCRIPTS uninstall-includeHEADERS \
+	uninstall-libLTLIBRARIES uninstall-pkgconfigDATA \
+	uninstall-pkgincludeHEADERS uninstall-pkglibDATA
+
+
+gfs-config: gfs-config.in
+gerris2D.pc: gerris2D.pc.in
+gerris2D3.pc: gerris2D3.pc.in
+gerris3D.pc: gerris3D.pc.in
+
+domain.c: version.h
+
+version.h: $(DARCS_VERSION)
+
+darcsversion:
+	sh darcsversion.sh
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/adaptive.c b/src/adaptive.c
new file mode 100644
index 0000000..839d592
--- /dev/null
+++ b/src/adaptive.c
@@ -0,0 +1,1153 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "adaptive.h"
+#include "solid.h"
+
+#include "graphic.h"
+
+/*#define DEBUG*/
+
+/**
+ * gfs_cell_coarse_init:
+ * @cell: a #FttCell.
+ * @domain: a #GfsDomain containing @cell.
+ *
+ * Initialises the variables of @cell using the values of its children
+ * cells.
+ */
+void gfs_cell_coarse_init (FttCell * cell, GfsDomain * domain)
+{
+  GSList * i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (cell));
+  g_return_if_fail (domain != NULL);
+
+  i = domain->variables;
+  while (i) {
+    GfsVariable * v = i->data;
+
+    (* v->fine_coarse) (cell, v);
+    i = i->next;
+  }
+}
+
+/* GfsAdapt: Object */
+
+typedef struct {
+  GfsSimulation * sim;
+  guint nc;
+  GtsEHeap * hcoarse, * hfine;
+  gdouble clim;
+  GfsVariable * hcoarsev, * hfinev, * costv, * c;
+} AdaptParams;
+
+static void gfs_adapt_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_ADAPT (o)->minlevel));
+  gts_object_destroy (GTS_OBJECT (GFS_ADAPT (o)->maxlevel));
+
+  (* GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class->destroy) (o);
+}
+
+static void none (FttCell * cell, GfsVariable * v) {}
+
+static void gfs_adapt_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsAdapt * a = GFS_ADAPT (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    else if (!strcmp (fp->token->str, "minlevel")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (a->minlevel, gfs_object_simulation (*o), fp);
+    }
+    else if (!strcmp (fp->token->str, "maxlevel")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (a->maxlevel, gfs_object_simulation (*o), fp);
+    }
+    else if (!strcmp (fp->token->str, "mincells")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting an integer (mincells)");
+	return;
+      }
+      a->mincells = atoi (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "maxcells")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting an integer (maxcells)");
+	return;
+      }
+      a->maxcells = atoi (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "cmax")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      a->cmax = gfs_read_constant (fp, gfs_object_simulation (*o));
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+    else if (!strcmp (fp->token->str, "weight")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      a->weight = gfs_read_constant (fp, gfs_object_simulation (*o));
+      if (fp->type == GTS_ERROR)      
+	return;
+    }
+    else if (!strcmp (fp->token->str, "cfactor")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      a->cfactor = gfs_read_constant (fp, gfs_object_simulation (*o));
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+    else if (!strcmp (fp->token->str, "c")) {
+      GfsDomain * domain;
+
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_STRING) {
+	gts_file_error (fp, "expecting a variable name");
+	return;
+      }
+      domain = GFS_DOMAIN (gfs_object_simulation (*o));
+      a->c = gfs_domain_get_or_add_variable (domain, fp->token->str, "Adaptive refinement cost");
+      if (!a->c) {
+	gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+	return;
+      }
+      a->c->fine_coarse = none;
+      gts_file_next_token (fp);
+    }
+    else {
+      gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+      return;
+    }
+  }
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void gfs_adapt_write (GtsObject * o, FILE * fp)
+{
+  GfsAdapt * a = GFS_ADAPT (o);
+
+  if (GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class->write) 
+      (o, fp);
+  fputs (" { minlevel =", fp);
+  gfs_function_write (a->minlevel, fp);
+  fputs (" maxlevel =", fp);
+  gfs_function_write (a->maxlevel, fp);
+  fputc (' ', fp);
+  if (a->mincells > 0)
+    fprintf (fp, "mincells = %u ", a->mincells);
+  if (a->maxcells < G_MAXINT)
+    fprintf (fp, "maxcells = %u ", a->maxcells);
+  if (a->cmax > 0.)
+    fprintf (fp, "cmax = %g ", a->cmax);
+  if (a->weight != 1.)
+    fprintf (fp, "weight = %g ", a->weight);
+  if (a->cfactor != 4.)
+    fprintf (fp, "cfactor = %g ", a->cfactor);
+  if (a->c != NULL)
+    fprintf (fp, "c = %s ", a->c->name);
+  fputc ('}', fp);
+}
+
+static gboolean gfs_adapt_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if (GFS_ADAPT (event)->cost == NULL) {
+    gts_object_destroy (GTS_OBJECT (event));
+    return FALSE;
+  }
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_adapt_class ())->parent_class)->event) 
+      (event, sim)) {
+    GFS_ADAPT (event)->active = TRUE;
+    return TRUE;
+  }
+  GFS_ADAPT (event)->active = FALSE;
+  return FALSE;
+}
+
+static void gfs_adapt_class_init (GfsEventClass * klass)
+{
+  klass->event = gfs_adapt_event;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_adapt_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_adapt_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_adapt_write;
+}
+
+static void gfs_adapt_init (GfsAdapt * object)
+{
+  object->active = FALSE;
+  object->minlevel = gfs_function_new (gfs_function_class (), 0);
+  object->maxlevel = gfs_function_new (gfs_function_class (), 5);
+  object->mincells = 0;
+  object->maxcells = G_MAXINT;
+  object->cmax = 0.;
+  object->weight = 1.;
+  object->cfactor = 4.;
+  object->c = NULL;
+}
+
+GfsEventClass * gfs_adapt_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_info = {
+      "GfsAdapt",
+      sizeof (GfsAdapt),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_adapt_class_init,
+      (GtsObjectInitFunc) gfs_adapt_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_adapt_info);
+  }
+
+  return klass;
+}
+
+/* GfsAdaptVorticity: Object */
+
+static gboolean gfs_adapt_vorticity_event (GfsEvent * event, 
+					   GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_adapt_vorticity_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsAdaptVorticity * a = GFS_ADAPT_VORTICITY (event);
+
+    a->u = gfs_domain_velocity (GFS_DOMAIN (sim));
+    a->maxa = gfs_domain_norm_velocity (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1).infty;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_adapt_vorticity_class_init (GfsEventClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_adapt_vorticity_event;
+}
+
+static gdouble cost_vorticity (FttCell * cell, GfsAdaptVorticity * a)
+{
+  if (a->maxa <= 0.)
+    return 0.;
+  return fabs (gfs_vorticity (cell, a->u))*ftt_cell_size (cell)/a->maxa;
+}
+
+static void gfs_adapt_vorticity_init (GfsAdaptVorticity * object)
+{
+  GFS_ADAPT (object)->cost = (GtsKeyFunc) cost_vorticity;
+}
+
+GfsEventClass * gfs_adapt_vorticity_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_vorticity_info = {
+      "GfsAdaptVorticity",
+      sizeof (GfsAdaptVorticity),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_adapt_vorticity_class_init,
+      (GtsObjectInitFunc) gfs_adapt_vorticity_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_adapt_class ()),
+				  &gfs_adapt_vorticity_info);
+  }
+
+  return klass;
+}
+
+/* GfsAdaptStreamlineCurvature: Object */
+
+static void gfs_adapt_streamline_curvature_init (GfsAdapt * object)
+{
+  object->cost = (GtsKeyFunc) gfs_streamline_curvature;
+}
+
+GfsEventClass * gfs_adapt_streamline_curvature_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_streamline_curvature_info = {
+      "GfsAdaptStreamlineCurvature",
+      sizeof (GfsAdapt),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) gfs_adapt_streamline_curvature_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_adapt_class ()),
+				  &gfs_adapt_streamline_curvature_info);
+  }
+
+  return klass;
+}
+
+/* GfsAdaptFunction: Object */
+
+static void gfs_adapt_function_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_ADAPT_FUNCTION (o)->f));
+
+  (* GTS_OBJECT_CLASS (gfs_adapt_function_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_adapt_function_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_adapt_function_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_function_read (GFS_ADAPT_FUNCTION (*o)->f, gfs_object_simulation (*o), fp);
+}
+
+static void gfs_adapt_function_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_adapt_function_class ())->parent_class->write) (o, fp);
+  gfs_function_write (GFS_ADAPT_FUNCTION (o)->f, fp);
+}
+
+static void gfs_adapt_function_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = gfs_adapt_function_destroy;  
+  klass->read = gfs_adapt_function_read;
+  klass->write = gfs_adapt_function_write;
+}
+
+static gdouble function_cost (FttCell * cell, GfsAdaptFunction * a)
+{
+  return gfs_function_value (a->f, cell);
+}
+
+static void gfs_adapt_function_init (GfsAdaptFunction * object)
+{
+  object->f = gfs_function_new (gfs_function_class (), 0.);
+  GFS_ADAPT (object)->cost = (GtsKeyFunc) function_cost;
+}
+
+GfsEventClass * gfs_adapt_function_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_function_info = {
+      "GfsAdaptFunction",
+      sizeof (GfsAdaptFunction),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_adapt_function_class_init,
+      (GtsObjectInitFunc) gfs_adapt_function_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_adapt_class ()),
+				  &gfs_adapt_function_info);
+  }
+
+  return klass;
+}
+
+/* GfsAdaptGradient: Object */
+
+static void gfs_adapt_gradient_destroy (GtsObject * o)
+{
+  if (GFS_ADAPT_GRADIENT (o)->v && !gfs_function_get_variable (GFS_ADAPT_FUNCTION (o)->f))
+    gts_object_destroy (GTS_OBJECT (GFS_ADAPT_GRADIENT (o)->v));
+
+  (* GTS_OBJECT_CLASS (gfs_adapt_gradient_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_adapt_gradient_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_adapt_gradient_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsAdaptGradient * a = GFS_ADAPT_GRADIENT (*o);
+  a->v = gfs_function_get_variable (GFS_ADAPT_FUNCTION (a)->f);
+  if (a->v == NULL)
+    a->v = gfs_temporary_variable (GFS_DOMAIN (gfs_object_simulation (a)));
+  a->dimension = pow (gfs_object_simulation (a)->physical_params.L, a->v->units);
+}
+
+static void update_f (FttCell * cell, GfsAdaptFunction * a)
+{
+  GFS_VALUE (cell, GFS_ADAPT_GRADIENT (a)->v) = gfs_function_value (a->f, cell);
+}
+
+static gboolean gfs_adapt_gradient_event (GfsEvent * event, 
+					  GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_adapt_gradient_class ())->parent_class)->event) 
+      (event, sim)) {
+    if (!gfs_function_get_variable (GFS_ADAPT_FUNCTION (event)->f)) {
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) update_f, event);
+      GfsVariable * v = GFS_ADAPT_GRADIENT (event)->v;
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+				FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				(FttCellTraverseFunc) v->fine_coarse, v);
+      gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_ALL, -1, v);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_adapt_gradient_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_adapt_gradient_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_adapt_gradient_read;
+  klass->event = gfs_adapt_gradient_event;
+}
+
+static gdouble gradient_cost (FttCell * cell, GfsAdaptGradient * a)
+{
+  FttComponent c;
+  gdouble sum2 = 0;
+  gdouble * lambda;
+
+  lambda = (gdouble *) &GFS_DOMAIN (gfs_object_simulation (a))->lambda;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble g = lambda[c]*gfs_center_gradient (cell, c, a->v->i);
+
+    sum2 += g*g;
+  }
+  return sqrt (sum2)*a->dimension;
+}
+
+static void gfs_adapt_gradient_init (GfsAdaptGradient * object)
+{
+  GFS_ADAPT (object)->cost = (GtsKeyFunc) gradient_cost;
+  GFS_ADAPT_GRADIENT (object)->dimension = 1.;
+}
+
+GfsEventClass * gfs_adapt_gradient_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_gradient_info = {
+      "GfsAdaptGradient",
+      sizeof (GfsAdaptGradient),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_adapt_gradient_class_init,
+      (GtsObjectInitFunc) gfs_adapt_gradient_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_adapt_function_class ()),
+				  &gfs_adapt_gradient_info);
+  }
+
+  return klass;
+}
+
+/* GfsAdaptError: Object */
+
+static void gfs_adapt_error_destroy (GtsObject * o)
+{
+  if (GFS_ADAPT_ERROR (o)->v != GFS_ADAPT (o)->c)
+    gts_object_destroy (GTS_OBJECT (GFS_ADAPT_ERROR (o)->v));
+
+  (* GTS_OBJECT_CLASS (gfs_adapt_error_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_adapt_error_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_adapt_error_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_ADAPT_ERROR (*o)->v = GFS_ADAPT (*o)->c ? GFS_ADAPT (*o)->c :
+    gfs_temporary_variable (GFS_DOMAIN (gfs_object_simulation (*o)));
+  GFS_ADAPT_ERROR (*o)->v->coarse_fine = none;
+  GFS_ADAPT_ERROR (*o)->v->fine_coarse = none;
+}
+
+static void compute_gradient (FttCell * cell, GfsAdaptError * a)
+{
+  GFS_VALUE (cell, a->dv) = gfs_center_regular_gradient (cell, a->dv->component, 
+							 GFS_ADAPT_GRADIENT (a)->v);
+}
+
+static void add_hessian_norm (FttCell * cell, GfsAdaptError * a)
+{
+  /* off-diagonal */
+  FttComponent j;
+  for (j = 0; j < FTT_DIMENSION; j++)
+    if (j != a->dv->component) {
+      gdouble g = gfs_center_regular_gradient (cell, j, a->dv);
+      GFS_VALUE (cell, a->v) += g*g;
+    }
+  /* diagonal */
+  gdouble g = gfs_center_regular_2nd_derivative (cell, a->dv->component, GFS_ADAPT_GRADIENT (a)->v);
+  GFS_VALUE (cell, a->v) += g*g;
+}
+
+static void scale (FttCell * cell, GfsAdaptError * a)
+{
+  GFS_VALUE (cell, a->v) = sqrt (GFS_VALUE (cell, a->v))/8.*GFS_ADAPT_GRADIENT (a)->dimension;
+}
+
+static gboolean gfs_adapt_error_event (GfsEvent * event, 
+				       GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_adapt_error_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsAdaptError * a = GFS_ADAPT_ERROR (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, a->v);
+    a->dv = gfs_temporary_variable (domain);
+    for (a->dv->component = 0; a->dv->component < FTT_DIMENSION; a->dv->component++) {
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+				(FttCellTraverseFunc) compute_gradient, a);
+      gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, a->dv);
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+				(FttCellTraverseFunc) add_hessian_norm, a);
+    }
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			      (FttCellTraverseFunc) scale, a);
+    gts_object_destroy (GTS_OBJECT (a->dv));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_adapt_error_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_adapt_error_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_adapt_error_read;
+  GFS_EVENT_CLASS (klass)->event = gfs_adapt_error_event;
+}
+
+static gdouble cost_error (FttCell * cell, GfsAdaptError * a)
+{
+  return GFS_VALUE (cell, a->v);
+}
+
+static void gfs_adapt_error_init (GfsAdapt * object)
+{
+  object->cost = (GtsKeyFunc) cost_error;
+  object->cfactor = 2.;
+}
+
+GfsEventClass * gfs_adapt_error_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_adapt_error_info = {
+      "GfsAdaptError",
+      sizeof (GfsAdaptError),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_adapt_error_class_init,
+      (GtsObjectInitFunc) gfs_adapt_error_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_adapt_gradient_class ()),
+				  &gfs_adapt_error_info);
+  }
+
+  return klass;
+}
+
+static void refine_cell_corner (FttCell * cell, GfsDomain * domain)
+{
+  if (ftt_refine_corner (cell))
+    ftt_cell_refine_single (cell, domain->cell_init, domain->cell_init_data);
+}
+
+/**
+ * @domain: a #GfsDomain.
+ * @depth: the depth of @domain.
+ *
+ * Force the grading of the tree hierarchy of domain, matches the
+ * boundaries, recomputes merged cells and applies the boundary
+ * conditions for all variables.
+ */
+void gfs_domain_reshape (GfsDomain * domain, guint depth)
+{
+  gint l;
+
+  g_return_if_fail (domain != NULL);
+
+  for (l = depth - 2; l >= 0; l--)
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+			      (FttCellTraverseFunc) refine_cell_corner,
+			      domain);
+  gfs_domain_match (domain);
+  gfs_set_merged (domain);
+  GSList * i = domain->variables;
+  while (i) {
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, i->data);
+    i = i->next;
+  }
+}
+
+#define CELL_COST(cell) (GFS_VARIABLE (cell, p->costv->i))
+#define CELL_HCOARSE(c) (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hcoarsev->i)))
+#define CELL_HFINE(c) (GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (c, p->hfinev->i)))
+
+static FttCell * remove_top_coarse (GtsEHeap * h, gdouble * cost, GfsVariable * hcoarse)
+{
+  FttCell * cell = gts_eheap_remove_top (h, cost);
+
+  if (cell)
+    GFS_VARIABLE (cell, hcoarse->i) = 0.;
+  while (cell && !FTT_CELL_IS_LEAF (cell)) {
+    cell = gts_eheap_remove_top (h, cost);
+    if (cell) 
+      GFS_VARIABLE (cell, hcoarse->i) = 0.;
+  }
+  return cell;
+}
+
+static FttCell * remove_top_fine (GtsEHeap * h, gdouble * cost, GfsVariable * hfine)
+{
+  FttCell * cell = gts_eheap_remove_top (h, cost);
+
+  if (cell)
+    GFS_VARIABLE (cell, hfine->i) = 0.;
+  while (cell && ftt_cell_depth (cell) - ftt_cell_level (cell) != 1) {
+    cell = gts_eheap_remove_top (h, cost);
+    if (cell) 
+      GFS_VARIABLE (cell, hfine->i) = 0.;
+  }
+  return cell;
+}
+
+static gdouble refine_cost (FttCell * cell, GfsSimulation * sim)
+{
+  GSList * i = sim->adapts->items;
+  gdouble cost = 0.;
+
+  while (i) {
+    GfsAdapt * a = i->data;
+
+    if (a->active && a->cost)
+      cost += a->weight*(* a->cost) (cell, a);
+    i = i->next;
+  }
+
+  return cost;
+}
+
+static void compute_cost (FttCell * cell, AdaptParams * p)
+{
+  gdouble cost = refine_cost (cell, p->sim);
+
+  GFS_VARIABLE (cell, p->hcoarsev->i) = GFS_VARIABLE (cell, p->hfinev->i) = 0.;
+  if (FTT_CELL_IS_LEAF (cell))
+    CELL_COST (cell) = cost;
+  else {
+    FttCellChildren child;
+    FttCellNeighbors n;
+    guint i, level = ftt_cell_level (cell);
+    FttCell * parent;
+    gdouble cmax = 0.;
+
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i] && CELL_COST (child.c[i]) > cmax)
+	cmax = CELL_COST (child.c[i]);
+    if (cmax > cost) cost = cmax;
+    if (cost > CELL_COST (cell)) CELL_COST (cell) = cost;
+
+    ftt_cell_neighbors (cell, &n);
+    for (i = 0; i < FTT_NEIGHBORS; i++)
+      if (n.c[i] && ftt_cell_level (n.c[i]) == level && 
+	  (parent = ftt_cell_parent (n.c[i])) &&
+	  cmax > CELL_COST (parent))
+	CELL_COST (parent) = cmax;
+  }
+  p->nc++;
+}
+
+static void store_cost (FttCell * cell, AdaptParams * p)
+{
+  GFS_VARIABLE (cell, p->c->i) = CELL_COST (cell);
+}
+
+static guint minlevel (FttCell * cell, GfsSimulation * sim)
+{
+  guint minlevel = 0;
+  GSList * i = sim->adapts->items;
+
+  while (i) {
+    GfsAdapt * a = i->data;
+    guint l;
+    
+    if (a->active && (l = gfs_function_value (a->minlevel, cell)) > minlevel)
+      minlevel = l;
+    i = i->next;
+  }
+  return minlevel;
+}
+
+static guint maxlevel (FttCell * cell, GfsSimulation * sim)
+{
+  GSList * i = sim->adapts->items;
+  guint maxlevel = G_MAXINT;
+
+  while (i) {
+    GfsAdapt * a = i->data;
+    guint l;
+
+    if (a->active && (l = gfs_function_value (a->maxlevel, cell)) < maxlevel)
+      maxlevel = l;
+    i = i->next;
+  }
+  return maxlevel;
+}
+
+static void fill_heaps (FttCell * cell, AdaptParams * p)
+{
+  guint level = ftt_cell_level (cell);
+  FttCell * parent = ftt_cell_parent (cell);
+  
+  if (level < maxlevel (cell, p->sim))
+    GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (cell, p->hcoarsev->i)) = 
+      gts_eheap_insert_with_key (p->hcoarse, cell, - CELL_COST (cell));
+  if (parent && !GFS_CELL_IS_PERMANENT (parent) && GFS_VARIABLE (parent, p->hfinev->i) == 0. &&
+      level > minlevel (parent, p->sim))
+    GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (parent, p->hfinev->i)) = 
+      gts_eheap_insert_with_key (p->hfine, parent, CELL_COST (parent));
+}
+
+static gboolean fine_cell_coarsenable (FttCell * cell, AdaptParams * p)
+{
+  if (GFS_CELL_IS_BOUNDARY (cell))
+    return TRUE;
+  if (GFS_CELL_IS_PERMANENT (cell))
+    return FALSE;
+  if (CELL_COST (cell) >= -p->clim)
+    return FALSE;
+  if (ftt_cell_level (cell) < minlevel (cell, p->sim))
+    return FALSE;
+  return TRUE;      
+}
+
+static void fine_cell_cleanup (FttCell * cell, AdaptParams * p)
+{
+  if (!GFS_CELL_IS_BOUNDARY (cell)) {
+    gpointer o;
+
+    p->nc--;
+    if ((o = CELL_HCOARSE (cell)))
+      gts_eheap_remove (p->hcoarse, o);
+    if ((o = CELL_HFINE (cell)))
+      gts_eheap_remove (p->hfine, o);
+  }
+  gfs_cell_cleanup (cell, GFS_DOMAIN (p->sim));
+}
+
+static void cell_fine_init (FttCell * cell, AdaptParams * p)
+{
+  FttCellChildren child;
+  GfsDomain * domain = GFS_DOMAIN (p->sim);
+  guint n;
+
+  (* domain->cell_init) (cell, domain->cell_init_data);
+  ftt_cell_children (cell, &child);
+  for (n = 0; n < FTT_CELLS; n++)
+    if (child.c[n])
+      CELL_COST (child.c[n]) = G_MAXDOUBLE;
+  if (!GFS_CELL_IS_BOUNDARY (cell))
+    p->nc += FTT_CELLS;
+}
+
+static gboolean adapt_global (GfsSimulation * simulation,
+			      guint * depth,
+			      GfsAdaptStats * s,
+			      guint mincells, guint maxcells,
+			      GfsVariable * c,
+			      gdouble cmax)
+{
+  GfsDomain * domain = GFS_DOMAIN (simulation);
+  gint l;
+  gdouble ccoarse = 0., cfine = 0.;
+  FttCell * coarse, * fine;
+  gboolean changed = TRUE, global_changed = FALSE;
+  AdaptParams apar;
+  
+  apar.sim = simulation;
+  apar.nc = 0;
+  apar.costv = gfs_temporary_variable (domain);
+  apar.hcoarsev = gfs_temporary_variable (domain);
+  apar.hfinev = gfs_temporary_variable (domain);
+  apar.hcoarse = gts_eheap_new (NULL, NULL);
+  apar.hfine = gts_eheap_new (NULL, NULL);
+  apar.c = c;
+  
+  gfs_domain_cell_traverse (domain, 
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, apar.costv);
+  for (l = *depth; l >= 0; l--)
+    gfs_domain_cell_traverse (domain, 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+			      (FttCellTraverseFunc) compute_cost, &apar);
+  if (apar.c)
+    gfs_domain_cell_traverse (domain, 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			      (FttCellTraverseFunc) store_cost, &apar);
+  gts_eheap_freeze (apar.hcoarse);
+  gts_eheap_freeze (apar.hfine);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) fill_heaps, &apar);
+  gts_eheap_thaw (apar.hcoarse);
+  gts_eheap_thaw (apar.hfine);
+  coarse = remove_top_coarse (apar.hcoarse, &ccoarse, apar.hcoarsev);
+  fine = remove_top_fine (apar.hfine, &cfine, apar.hfinev);
+#ifdef DEBUG
+  fprintf (stderr, "initial: %g %g %d\n", cfine, -ccoarse, apar.nc);
+#endif /* DEBUG */
+  while (changed) {
+#ifdef DEBUG
+    fprintf (stderr, "%g %g %d\n", cfine, -ccoarse, apar.nc);
+#endif /* DEBUG */
+    changed = FALSE;
+    if (fine && ((cfine < -ccoarse && apar.nc > maxcells) || 
+		 (cfine < cmax && apar.nc >= mincells))) {
+      guint n = apar.nc;
+	
+      apar.clim = MIN (ccoarse, -cmax);
+      ftt_cell_coarsen (fine,
+			(FttCellCoarsenFunc) fine_cell_coarsenable, &apar,
+			(FttCellCleanupFunc) fine_cell_cleanup, &apar);
+#ifdef DEBUG
+      fprintf (stderr, "coarsen: %d\n", apar.nc);
+#endif /* DEBUG */
+      fine = remove_top_fine (apar.hfine, &cfine, apar.hfinev);
+      s->removed += n - apar.nc;
+      changed = global_changed = TRUE;
+    }
+    if (coarse && ((-ccoarse > cfine && apar.nc < mincells) ||
+		   (-ccoarse > cmax && apar.nc <= maxcells))) {
+      guint level = ftt_cell_level (coarse), n = apar.nc;
+	
+      ftt_cell_refine_corners (coarse, (FttCellInitFunc) cell_fine_init, &apar);
+      ftt_cell_refine_single (coarse, (FttCellInitFunc) cell_fine_init, &apar);
+      if (level + 1 > *depth)
+	*depth = level + 1;
+#ifdef DEBUG
+      fprintf (stderr, "refine: %d\n", apar.nc);
+#endif /* DEBUG */
+      coarse = remove_top_coarse (apar.hcoarse, &ccoarse, apar.hcoarsev);
+      s->created += apar.nc - n;
+      changed = global_changed = TRUE;
+    }
+  }
+  gts_range_add_value (&s->cmax, -ccoarse);
+  gts_range_add_value (&s->ncells, apar.nc);
+
+  gts_eheap_destroy (apar.hcoarse);
+  gts_eheap_destroy (apar.hfine);
+  gts_object_destroy (GTS_OBJECT (apar.costv));
+  gts_object_destroy (GTS_OBJECT (apar.hcoarsev));
+  gts_object_destroy (GTS_OBJECT (apar.hfinev));  
+
+  return global_changed;
+}
+
+typedef struct {
+  GfsSimulation * sim;
+  guint depth, nc;
+  GfsVariable * r, * c;
+  GfsAdaptStats * s;
+  gboolean changed;
+} AdaptLocalParams;
+
+#define REFINABLE(cell, p) (GFS_VALUE (cell, (p)->r))
+#define COARSENABLE(cell, p) (GFS_VALUE (cell, (p)->c))
+
+static gboolean coarsen_cell (FttCell * cell, AdaptLocalParams * p)
+{
+  if (GFS_CELL_IS_BOUNDARY (cell))
+    return TRUE;
+  return COARSENABLE (cell, p);
+}
+
+static void cell_cleanup (FttCell * cell, AdaptLocalParams * p)
+{
+  gfs_cell_cleanup (cell, GFS_DOMAIN (p->sim));
+  p->s->removed++;
+  p->nc--;
+  p->changed = TRUE;
+}
+
+static void coarsen_box (GfsBox * box, AdaptLocalParams * p)
+{
+  ftt_cell_coarsen (box->root,
+		    (FttCellCoarsenFunc) coarsen_cell, p,
+		    (FttCellCleanupFunc) cell_cleanup, p);
+}
+
+static void local_cell_fine_init (FttCell * parent,  AdaptLocalParams * p)
+{
+  GfsDomain * domain = GFS_DOMAIN (p->sim);
+  (* domain->cell_init) (parent, domain->cell_init_data);
+  if (!GFS_CELL_IS_BOUNDARY (parent)) {
+    p->s->created += FTT_CELLS;
+    p->nc += FTT_CELLS;
+  }
+}
+
+static void refine_cell (FttCell * cell, AdaptLocalParams * p)
+{
+  if (REFINABLE (cell, p)) {
+    guint level = ftt_cell_level (cell);
+
+    ftt_cell_refine_corners (cell, (FttCellInitFunc) local_cell_fine_init, p);
+    ftt_cell_refine_single (cell, (FttCellInitFunc) local_cell_fine_init, p);
+    if (level + 1 > p->depth)
+      p->depth = level + 1;
+    p->changed = TRUE;
+  }
+}
+
+static void refine_cell_mark (FttCell * cell, AdaptLocalParams * p)
+{
+  p->nc++;
+  REFINABLE (cell, p) = FALSE;
+  COARSENABLE (cell, p) = !GFS_CELL_IS_PERMANENT (cell);
+
+  guint level = ftt_cell_level (cell);
+  GSList * i = p->sim->adapts->items;
+  while (i) {
+    GfsAdapt * a = i->data;
+    if (a->active) {
+      guint minlevel = gfs_function_value (a->minlevel, cell);
+      guint maxlevel = gfs_function_value (a->maxlevel, cell);
+      if (FTT_CELL_IS_LEAF (cell) && 
+	  (level < minlevel ||
+	   (level < maxlevel && (* a->cost) (cell, a) > a->cmax))) {
+	REFINABLE (cell, p) = TRUE;
+	COARSENABLE (cell, p) = FALSE;
+	return;
+      }
+      if (level < minlevel || (level < maxlevel && (* a->cost) (cell, a) > a->cmax/a->cfactor))
+	COARSENABLE (cell, p) = FALSE;
+    }
+    i = i->next;
+  }
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCell * parent = ftt_cell_parent (cell);    
+    if (parent)
+      COARSENABLE (parent, p) = FALSE;
+  }
+}
+
+static gboolean adapt_local (GfsSimulation * sim, guint * depth, GfsAdaptStats * s)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  AdaptLocalParams p;
+  p.sim = sim;
+  p.depth = *depth;
+  p.r = gfs_temporary_variable (domain);
+  p.c = gfs_temporary_variable (domain);
+  p.s = s;
+  p.nc = 0;
+  p.changed = FALSE;
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) refine_cell_mark, &p);
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) refine_cell, &p);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) coarsen_box, &p);
+  gts_object_destroy (GTS_OBJECT (p.r));
+  gts_object_destroy (GTS_OBJECT (p.c));
+  *depth = p.depth;
+
+  gts_range_add_value (&s->ncells, p.nc);
+  return p.changed;
+}
+
+/**
+ * gfs_simulation_adapt:
+ * @simulation: a #GfsSimulation.
+ * @s: where to put statistics (or %NULL).
+ *
+ * Checks if any mesh adaptation is necessary and adapts the mesh
+ * using an OR combination of all the regular criteria defined in
+ * @simulation->adapts.
+ * 
+ * If any one or several criteria are defined as "not" refinements,
+ * the mesh will be refined only if all of this criteria AND any other
+ * regular criterion is verified.  
+ */
+void gfs_simulation_adapt (GfsSimulation * simulation)
+{
+  gboolean active = FALSE;
+  guint mincells = 0, maxcells = G_MAXINT;
+  GfsDomain * domain;
+  gdouble cmax = 0.;
+  GfsVariable * c = NULL;
+
+  g_return_if_fail (simulation != NULL);
+
+  domain = GFS_DOMAIN (simulation);
+
+  gfs_domain_timer_start (domain, "adapt");
+
+  GSList * i = simulation->adapts->items;
+  while (i) {
+    GfsAdapt * a = i->data;
+
+    if (a->active) {
+      if (a->maxcells < maxcells) maxcells = a->maxcells;
+      if (a->mincells > mincells) mincells = a->mincells;
+      cmax += a->cmax;
+      active = TRUE;
+      if (a->c)
+	c = a->c;
+    }
+    i = i->next;
+  }
+  if (active) {
+    guint depth = gfs_domain_depth (domain);
+    gboolean changed;
+
+    if (maxcells < G_MAXINT)
+      changed = adapt_global (simulation, &depth, &simulation->adapts_stats, 
+			      mincells, maxcells, c, cmax);
+    else
+      changed = adapt_local (simulation, &depth, &simulation->adapts_stats);
+
+    gfs_all_reduce (domain, changed, MPI_INT, MPI_MAX);
+    if (changed)
+      gfs_domain_reshape (domain, depth);
+  }
+
+  gfs_domain_timer_stop (domain, "adapt");
+}
+
+/**
+ * gfs_adapt_stats_init:
+ * @s: the #GfsAdaptStats.
+ *
+ * Initializes or reset @s.
+ */
+void gfs_adapt_stats_init (GfsAdaptStats * s)
+{
+  g_return_if_fail (s != NULL);
+
+  s->removed = 0;
+  s->created = 0;
+  gts_range_init (&s->cmax);
+  gts_range_init (&s->ncells);
+}
+
+/**
+ * gfs_adapt_stats_update:
+ * @s: the #GfsAdaptStats.
+ *
+ * Updates @s.
+ */
+void gfs_adapt_stats_update (GfsAdaptStats * s)
+{
+  g_return_if_fail (s != NULL);
+
+  gts_range_update (&s->cmax);
+  gts_range_update (&s->ncells);
+}
diff --git a/src/adaptive.h b/src/adaptive.h
new file mode 100644
index 0000000..4747c22
--- /dev/null
+++ b/src/adaptive.h
@@ -0,0 +1,157 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __ADAPTIVE_H__
+#define __ADAPTIVE_H__
+
+#include "simulation.h"
+#include "event.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void          gfs_cell_coarse_init          (FttCell * cell,
+					     GfsDomain * domain);
+void          gfs_adapt_stats_init          (GfsAdaptStats * s);
+void          gfs_adapt_stats_update        (GfsAdaptStats * s);
+void          gfs_simulation_adapt          (GfsSimulation * simulation);
+void          gfs_domain_reshape            (GfsDomain * domain,
+					     guint depth);
+
+/* GfsAdapt: Header */
+
+typedef struct _GfsAdapt         GfsAdapt;
+
+struct _GfsAdapt {
+  /*< private >*/
+  GfsEvent parent;
+  gboolean active;
+
+  /*< public >*/
+  GfsFunction * minlevel, * maxlevel;
+  guint mincells, maxcells;
+  gdouble cmax, weight, cfactor;
+  GfsVariable * c;
+  GtsKeyFunc cost;
+};
+
+#define GFS_ADAPT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsAdapt,\
+					         gfs_adapt_class ())
+#define GFS_IS_ADAPT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_class ()))
+
+GfsEventClass * gfs_adapt_class  (void);
+
+/* GfsAdaptVorticity: Header */
+
+typedef struct _GfsAdaptVorticity         GfsAdaptVorticity;
+
+struct _GfsAdaptVorticity {
+  /*< private >*/
+  GfsAdapt parent;
+  GfsVariable ** u;
+  gdouble maxa;
+
+  /*< public >*/
+};
+
+#define GFS_ADAPT_VORTICITY(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsAdaptVorticity,\
+					         gfs_adapt_vorticity_class ())
+#define GFS_IS_ADAPT_VORTICITY(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_vorticity_class ()))
+
+GfsEventClass * gfs_adapt_vorticity_class  (void);
+ 
+/* GfsAdaptStreamlineCurvature: Header */
+
+#define GFS_IS_ADAPT_STREAMLINE_CURVATURE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_streamline_curvature_class ()))
+
+GfsEventClass * gfs_adapt_streamline_curvature_class  (void);
+ 
+/* GfsAdaptFunction: Header */
+
+typedef struct _GfsAdaptFunction         GfsAdaptFunction;
+
+struct _GfsAdaptFunction {
+  /*< private >*/
+  GfsAdapt parent;
+
+  /*< public >*/
+  GfsFunction * f;
+};
+
+#define GFS_ADAPT_FUNCTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsAdaptFunction,\
+					         gfs_adapt_function_class ())
+#define GFS_IS_ADAPT_FUNCTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_function_class ()))
+
+GfsEventClass * gfs_adapt_function_class  (void);
+
+/* GfsAdaptGradient: Header */
+
+typedef struct _GfsAdaptGradient         GfsAdaptGradient;
+
+struct _GfsAdaptGradient {
+  /*< private >*/
+  GfsAdaptFunction parent;
+  gdouble dimension;
+
+  /*< public >*/
+  GfsVariable * v;
+};
+
+#define GFS_ADAPT_GRADIENT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsAdaptGradient,\
+					         gfs_adapt_gradient_class ())
+#define GFS_IS_ADAPT_GRADIENT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_gradient_class ()))
+
+GfsEventClass * gfs_adapt_gradient_class  (void);
+
+/* GfsAdaptError: Header */
+
+typedef struct _GfsAdaptError         GfsAdaptError;
+
+struct _GfsAdaptError {
+  /*< private >*/
+  GfsAdaptGradient parent;
+  GfsVariable * dv;
+
+  /*< public >*/
+  GfsVariable * v;
+};
+
+#define GFS_ADAPT_ERROR(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsAdaptError,\
+					         gfs_adapt_error_class ())
+#define GFS_IS_ADAPT_ERROR(obj)         (gts_object_is_from_class (obj,\
+						 gfs_adapt_error_class ()))
+
+GfsEventClass * gfs_adapt_error_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ADAPTIVE_H__ */
diff --git a/src/advection.c b/src/advection.c
new file mode 100644
index 0000000..c0e9f50
--- /dev/null
+++ b/src/advection.c
@@ -0,0 +1,1044 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "advection.h"
+#include "source.h"
+
+static gdouble transverse_term (FttCell * cell,
+				gdouble * msize,
+				FttComponent c,
+				const GfsAdvectionParams * par)
+{
+  GfsStateVector * s = GFS_STATE (cell);
+  gdouble vtan = par->use_centered_velocity ? 
+    GFS_VALUE (cell, par->u[c]) :
+    (s->f[2*c].un + s->f[2*c + 1].un)/2.;
+  FttCellFace f;
+  GfsGradient gf;
+  gdouble g;
+  
+  f.d = vtan > 0. ? 2*c + 1 : 2*c;
+  f.cell = cell;
+  f.neighbor = ftt_cell_neighbor (cell, f.d);
+  gfs_face_gradient (&f, &gf, par->v->i, -1);
+  g = gf.b - gf.a*GFS_VALUE (cell, par->v);
+  if (vtan > 0.) g = - g;
+  return par->dt*vtan*g/(2.*msize[c]);
+}
+
+/**
+ * gfs_cell_advected_face_values:
+ * @cell: a #FttCell.
+ * @par: the advection parameters.
+ *
+ * Fills the face variable (@v field of #GfsFaceStateVector) of all the
+ * faces of @cell with the advected value of variable @par->v at time
+ * t + dt/2.
+ */
+void gfs_cell_advected_face_values (FttCell * cell,
+				    const GfsAdvectionParams * par)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (par != NULL);
+
+  GfsStateVector * s = GFS_STATE (cell);
+  gdouble size = ftt_cell_size (cell), msize[FTT_DIMENSION];
+
+  FttComponent c;
+  if (par->v->domain->scale_metric)
+    for (c = 0; c < FTT_DIMENSION; c++)
+      msize[c] = size*(* par->v->domain->scale_metric) (par->v->domain, cell, c);
+  else
+    for (c = 0; c < FTT_DIMENSION; c++)
+      msize[c] = size;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble unorm = par->use_centered_velocity ?
+      par->dt*GFS_VALUE (cell, par->u[c])/msize[c] :
+       par->dt*(s->f[2*c].un + s->f[2*c + 1].un)/(2.*msize[c]);
+    gdouble g = (* par->gradient) (cell, c, par->v->i);
+    gdouble vl = GFS_VALUE (cell, par->v) + MIN ((1. - unorm)/2., 0.5)*g;
+    gdouble vr = GFS_VALUE (cell, par->v) + MAX ((- 1. - unorm)/2., -0.5)*g;
+    gdouble src = par->dt*gfs_variable_mac_source (par->v, cell)/2.;
+    gdouble dv;
+
+#if FTT_2D
+    dv = transverse_term (cell, msize, FTT_ORTHOGONAL_COMPONENT (c), par);
+#else  /* FTT_3D */
+    static FttComponent orthogonal[FTT_DIMENSION][2] = {
+      {FTT_Y, FTT_Z}, {FTT_X, FTT_Z}, {FTT_X, FTT_Y}
+    };
+
+    dv =  transverse_term (cell, msize, orthogonal[c][0], par);
+    dv += transverse_term (cell, msize, orthogonal[c][1], par);
+#endif /* FTT_3D */
+
+    s->f[2*c].v     = vl + src - dv;
+    s->f[2*c + 1].v = vr + src - dv;
+  }
+}
+
+/**
+ * gfs_cell_non_advected_face_values:
+ * @cell: a #FttCell.
+ * @par: the (non)advection parameters.
+ *
+ * Fills the face variable (@v field of #GfsFaceStateVector) of all the
+ * faces of @cell with the non-advected value of variable @par->v at time
+ * t + dt/2.
+ */
+void gfs_cell_non_advected_face_values (FttCell * cell,
+					const GfsAdvectionParams * par)
+{
+  FttComponent c;
+  GfsStateVector * s;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (par != NULL);
+
+  s = GFS_STATE (cell);
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble g = (* par->gradient) (cell, c, par->v->i);
+    gdouble vl = GFS_VALUE (cell, par->v) + g/2.;
+    gdouble vr = GFS_VALUE (cell, par->v) - g/2.;
+    gdouble src = par->dt*gfs_variable_mac_source (par->v, cell)/2.;
+
+    s->f[2*c].v     = vl + src;
+    s->f[2*c + 1].v = vr + src;
+  }
+}
+
+#if FTT_2D
+
+static gdouble interpolate_1D1 (const FttCell * cell,
+				FttDirection dright,
+				FttDirection dup,
+				gdouble x)
+{
+  FttCell * n;
+  FttDirection dleft;
+  GfsStateVector * s;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  dleft = FTT_OPPOSITE_DIRECTION (dright);
+  n = ftt_cell_neighbor (cell, dup);
+  s = GFS_STATE (cell);
+  if (n && !GFS_CELL_IS_BOUNDARY (n)) {
+    gdouble s1 = s->solid ? s->solid->s[dleft] : 1., s2;
+    gdouble v1 = s->f[dleft].v, v2;
+
+    g_assert (s1 > 0.);
+    /* check for corner refinement violation (topology.fig) */
+    g_assert (ftt_cell_level (n) == ftt_cell_level (cell));
+
+    if (FTT_CELL_IS_LEAF (n)) {
+      v2 = GFS_STATE (n)->f[dleft].v;
+      s2 = GFS_IS_MIXED (n) ? GFS_STATE (n)->solid->s[dleft] : 1.;
+    }
+    else {
+      FttDirection d[FTT_DIMENSION];
+
+      d[0] = dleft;
+      d[1] = FTT_OPPOSITE_DIRECTION (dup);
+      n = ftt_cell_child_corner (n, d);
+      if (n) {
+	v2 = GFS_STATE (n)->f[dleft].v;
+	s2 = GFS_IS_MIXED (n) ? GFS_STATE (n)->solid->s[dleft]/2. : 0.5;
+      }
+      else
+	s2 = v2 = 0.;
+    }
+    return s2 > 0. ? (v2*(s1 - 1. + 2.*x) + v1*(s2 + 1. - 2.*x))/(s1 + s2) : v1;
+  }
+  return s->f[dleft].v;
+}
+
+#elif FTT_2D3
+
+static gdouble interpolate_1D1 (const FttCell * cell,
+				FttDirection dright,
+				FttDirection dup,
+				gdouble x)
+{
+  FttCell * n;
+  FttDirection dleft;
+  GfsStateVector * s;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  dleft = FTT_OPPOSITE_DIRECTION (dright);
+  n = ftt_cell_neighbor (cell, dup);
+  s = GFS_STATE (cell);
+  if (n && !GFS_CELL_IS_BOUNDARY (n)) {
+    /* check for corner refinement violation (topology.fig) */
+    g_assert (ftt_cell_level (n) == ftt_cell_level (cell));
+
+    if (FTT_CELL_IS_LEAF (n))
+      return GFS_STATE (n)->f[dleft].v*x + s->f[dleft].v*(1. - x);
+    else {
+      FttDirection d[FTT_DIMENSION];
+
+      d[0] = dleft;
+      d[1] = FTT_OPPOSITE_DIRECTION (dup);
+      g_assert (d[0] < FTT_NEIGHBORS_2D);
+      g_assert (d[1] < FTT_NEIGHBORS_2D);
+      d[2] = 0;
+      n = ftt_cell_child_corner (n, d);
+      if (n)
+	return (GFS_STATE (n)->f[dleft].v*4.*x + s->f[dleft].v*(3. - 4.*x))/3.;
+    }
+  }
+  return s->f[dleft].v;
+}
+
+#else /* FTT_3D */
+
+static gdouble interpolate_2D1 (const FttCell * cell,
+				FttDirection dright,
+				FttDirection d1, FttDirection d2,
+				gdouble x, gdouble y)
+{
+  FttCell * n1, * n2;
+  gdouble x1 = 0., y1 = 1.;
+  gdouble x2 = 1., y2 = 0.;
+  gdouble v0, v1, v2;
+  FttDirection dleft;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  /* fixme: this routine does not take into account mixed cells
+     fractions (in contrast to interpolate_1D1 above) */
+
+  dleft = FTT_OPPOSITE_DIRECTION (dright);
+  v0 = GFS_STATE (cell)->f[dleft].v;
+
+  n1 = ftt_cell_neighbor (cell, d1);
+  if (n1 && !GFS_CELL_IS_BOUNDARY (n1)) {
+    /* check for corner refinement violation (topology.fig) */
+    g_assert (ftt_cell_level (n1) == ftt_cell_level (cell));
+
+    if (!FTT_CELL_IS_LEAF (n1)) {
+      FttDirection d[FTT_DIMENSION];
+
+      d[0] = FTT_OPPOSITE_DIRECTION (dright);
+      d[1] = FTT_OPPOSITE_DIRECTION (d1);
+      d[2] = d2;
+      if ((n1 = ftt_cell_child_corner (n1, d))) {
+	v1 = GFS_STATE (n1)->f[dleft].v;
+	x1 = 1./4.;
+	y1 = 3./4.;
+      }
+      else
+	v1 = v0;
+    }
+    else
+      v1 = GFS_STATE (n1)->f[dleft].v;
+  }
+  else
+    v1 = v0;
+
+  n2 = ftt_cell_neighbor (cell, d2);
+  if (n2 && !GFS_CELL_IS_BOUNDARY (n2)) {
+    /* check for corner refinement violation (topology.fig) */
+    g_assert (ftt_cell_level (n2) == ftt_cell_level (cell));
+
+    if (!FTT_CELL_IS_LEAF (n2)) {
+      FttDirection d[FTT_DIMENSION];
+
+      d[0] = FTT_OPPOSITE_DIRECTION (dright);
+      d[1] = FTT_OPPOSITE_DIRECTION (d2);
+      d[2] = d1;
+      if ((n2 = ftt_cell_child_corner (n2, d))) {
+	v2 = GFS_STATE (n2)->f[dleft].v;
+	x2 = 3./4.;
+	y2 = 1./4.;
+      }
+      else
+	v2 = v0;
+    }
+    else
+      v2 = GFS_STATE (n2)->f[dleft].v;
+  }
+  else
+    v2 = v0;
+
+  return ((v1 - v0)*(x*y2 - x2*y) + (v2 - v0)*(x1*y - x*y1))/
+    (x1*y2 - x2*y1) + v0;
+}
+
+#endif /* FTT_3D */
+
+/**
+ * gfs_face_upwinded_value:
+ * @face: a #FttCellFace.
+ * @upwinding: type of upwinding.
+ * @u: the cell-centered velocity.
+ *
+ * This function assumes that the face variable has been previously
+ * defined using gfs_cell_advected_face_values().
+ *
+ * Returns: the upwinded value of the face variable.  
+ */
+gdouble gfs_face_upwinded_value (const FttCellFace * face,
+				 GfsUpwinding upwinding,
+				 GfsVariable ** u)
+{
+  gdouble un = 0.;
+
+  g_return_val_if_fail (face != NULL, 0.);
+
+  if (GFS_FACE_FRACTION (face) == 0.)
+    return 0.;
+
+  switch (upwinding) {
+  case GFS_CENTERED_UPWINDING:
+    g_return_val_if_fail (u != NULL, 0.);
+    un = gfs_face_interpolated_value (face, u[face->d/2]->i); 
+    break;
+  case GFS_FACE_UPWINDING:
+    un = GFS_FACE_NORMAL_VELOCITY (face); 
+    break;
+  case GFS_NO_UPWINDING:
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+  if (!FTT_FACE_DIRECT (face))
+    un = - un;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    return 
+      un > 0. ? GFS_STATE (face->cell)->f[face->d].v :
+      un < 0. ? GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v :
+      (GFS_STATE (face->cell)->f[face->d].v +
+       GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v)/2.;
+  case FTT_FINE_COARSE:
+    if (un > 0.)
+      return GFS_STATE (face->cell)->f[face->d].v;
+    else {
+      gdouble vcoarse;
+#if (FTT_2D || FTT_2D3)
+      gint dp;
+      static gint perpendicular[FTT_NEIGHBORS_2D][FTT_CELLS] = 
+      {{-1,  2, -1,  3},
+       { 2, -1,  3, -1},
+       { 1,  0, -1, -1},
+       {-1, -1,  1,  0}};
+#else  /* FTT_3D */
+      gint * dp;
+      static gint perpendicular[FTT_NEIGHBORS][FTT_CELLS][2] = 
+      {{{-1,-1},{2,4},{-1,-1},{3,4},{-1,-1},{2,5},{-1,-1},{3,5}},
+       {{2,4},{-1,-1},{3,4},{-1,-1},{2,5},{-1,-1},{3,5},{-1,-1}},
+       {{4,1},{4,0},{-1,-1},{-1,-1},{5,1},{5,0},{-1,-1},{-1,-1}},
+       {{-1,-1},{-1,-1},{4,1},{4,0},{-1,-1},{-1,-1},{5,1},{5,0}},
+       {{1,2},{0,2},{1,3},{0,3},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
+       {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{1,2},{0,2},{1,3},{0,3}}};
+#endif /* FTT_3D */
+
+#if FTT_2D3
+      g_assert (face->d < FTT_NEIGHBORS_2D);
+#endif
+
+      dp = perpendicular[face->d][FTT_CELL_ID (face->cell)];
+#if (FTT_2D || FTT_2D3)
+      g_assert (dp >= 0);
+      vcoarse = interpolate_1D1 (face->neighbor, face->d, dp, 1./4.);
+#else  /* FTT_3D */
+      g_assert (dp[0] >= 0 && dp[1] >= 0);
+      vcoarse = interpolate_2D1 (face->neighbor, face->d,
+				 dp[0], dp[1], 
+				 1./4., 1./4.);
+#endif /* FTT_3D */
+      if (un == 0.)
+	return (GFS_STATE (face->cell)->f[face->d].v + vcoarse)/2.;
+      else
+	return vcoarse;
+    }
+  default:
+    g_assert_not_reached ();
+  }
+  return 0.;
+}
+
+/**
+ * gfs_face_advection_flux:
+ * @face: a #FttCellFace.
+ * @par: the advection parameters.
+ *
+ * Adds to variable @par->fv, the value of the (conservative)
+ * advection flux of the face variable through @face.
+ *
+ * This function assumes that the face variable has been previously
+ * defined using gfs_cell_advected_face_values().
+ */
+void gfs_face_advection_flux (const FttCellFace * face,
+			      const GfsAdvectionParams * par)
+{
+  gdouble flux;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (par != NULL);
+
+  flux = gfs_domain_face_fraction (par->v->domain, face)*GFS_FACE_NORMAL_VELOCITY (face)*par->dt*
+    gfs_face_upwinded_value (face, GFS_FACE_UPWINDING, NULL)/ftt_cell_size (face->cell);
+
+  if (!FTT_FACE_DIRECT (face))
+    flux = - flux;
+  GFS_VALUE (face->cell, par->fv) -= flux;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_VALUE (face->neighbor, par->fv) += flux;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_VALUE (face->neighbor, par->fv) += flux/FTT_CELLS;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_face_velocity_advection_flux:
+ * @face: a #FttCellFace.
+ * @par: the advection parameters.
+ *
+ * Adds to variable @par->fv, the value of the (conservative)
+ * advection flux through @face of variable @par->v (a component
+ * of the velocity).
+ *
+ * This function assumes that the @g field of the cells sharing @face
+ * are filled with the pressure gradient at time t + dt/2.  
+ *
+ * This function also assumes that the face value of @par->v has been
+ * previously defined using gfs_cell_advected_face_values().  
+ */
+void gfs_face_velocity_advection_flux (const FttCellFace * face,
+				       const GfsAdvectionParams * par)
+{
+  gdouble flux;
+  FttComponent c;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (par != NULL);
+
+  c = par->v->component;
+  g_return_if_fail (c >= 0 && c < FTT_DIMENSION);
+
+  flux = gfs_domain_face_fraction (par->v->domain, face)*GFS_FACE_NORMAL_VELOCITY (face)*par->dt
+    /ftt_cell_size (face->cell);
+#if 0
+  if (c == face->d/2) /* normal component */
+    flux *= GFS_FACE_NORMAL_VELOCITY (face);
+  else /* tangential component */
+#else
+    flux *= gfs_face_upwinded_value (face, par->upwinding, par->u)
+      /* pressure correction */
+      - gfs_face_interpolated_value (face, par->g[c]->i)*par->dt/2.;
+#endif
+  if (!FTT_FACE_DIRECT (face))
+    flux = - flux;
+  GFS_VALUE (face->cell, par->fv) -= flux;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_VALUE (face->neighbor, par->fv) += flux;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_VALUE (face->neighbor, par->fv) += flux/FTT_CELLS;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_face_velocity_convective_flux:
+ * @face: a #FttCellFace.
+ * @par: the advection parameters.
+ *
+ * Adds to variable @par->fv, the value of the (non-conservative)
+ * convective flux through @face of variable @par->v (a component
+ * of the velocity).
+ *
+ * This function assumes that the @g field of the cells sharing @face
+ * are filled with the pressure gradient at time t + dt/2.  
+ *
+ * This function also assumes that the face value of @par->v has been
+ * previously defined using gfs_cell_advected_face_values().  
+ */
+void gfs_face_velocity_convective_flux (const FttCellFace * face,
+					const GfsAdvectionParams * par)
+{
+  gdouble u;
+  FttComponent c;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (gfs_domain_face_fraction (par->v->domain, face) == 1.);
+
+  c = par->v->component;
+  g_return_if_fail (c >= 0 && c < FTT_DIMENSION);
+
+#if 0
+  if (c == face->d/2) /* normal component */
+    u = GFS_FACE_NORMAL_VELOCITY (face);
+  else /* tangential component */
+    u = gfs_face_upwinded_value (face, par->upwinding)
+      /* pressure correction */
+      - gfs_face_interpolated_value (face, GFS_GRADIENT_INDEX (c))*par->dt/2.;
+#else
+  u = gfs_face_upwinded_value (face, par->upwinding, par->u)
+    /* pressure correction */
+    - gfs_face_interpolated_value (face, par->g[c]->i)*par->dt/2.;
+#endif
+  u *= par->dt/(2.*ftt_cell_size (face->cell));
+  if (!FTT_FACE_DIRECT (face))
+    u = - u;
+  GFS_VALUE (face->cell, par->fv) -= 
+    u*(GFS_STATE (face->cell)->f[face->d].un + 
+       GFS_STATE (face->cell)->f[FTT_OPPOSITE_DIRECTION (face->d)].un);
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_VALUE (face->neighbor, par->fv) += 
+      u*(GFS_STATE (face->neighbor)->f[face->d].un + 
+	 GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].un);
+    break;
+  case FTT_FINE_COARSE:
+    GFS_VALUE (face->neighbor, par->fv) += 
+      u*(GFS_STATE (face->neighbor)->f[face->d].un + 
+	 GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].un)
+      /FTT_CELLS;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_face_advected_normal_velocity:
+ * @face: a #FttCellFace.
+ * @par: the #GfsAdvectionParams.
+ *
+ * Fills the normal component of the velocity at @face with the value
+ * advected (to time t + dt/2) from the centered velocities.
+ *
+ * This function assumes that the face variable has been previously
+ * defined for the correct component of the velocity using
+ * gfs_cell_advected_face_values().  
+ */
+void gfs_face_advected_normal_velocity (const FttCellFace * face,
+					const GfsAdvectionParams * par)
+{
+  gdouble u;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (par != NULL);
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) = u = 
+    gfs_face_upwinded_value (face, par->upwinding, par->u);
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) = u;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) += 
+      u*gfs_domain_face_fraction (par->v->domain, face)/
+      (gfs_domain_face_fraction_right (par->v->domain, face)*FTT_CELLS_DIRECTION (face->d));
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_face_interpolated_normal_velocity:
+ * @face: a #FttCellFace.
+ * @v: the velocity.
+ *
+ * Fills the normal component of the velocity at @face with the value
+ * interpolated from the centered velocities.
+ */
+void gfs_face_interpolated_normal_velocity (const FttCellFace * face, GfsVariable ** v)
+{
+  gdouble u;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (v != NULL);
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) = u = gfs_face_interpolated_value (face, v[face->d/2]->i);
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) = u;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) += 
+      u*gfs_domain_face_fraction (v[0]->domain, face)/
+      (gfs_domain_face_fraction_right (v[0]->domain, face)*FTT_CELLS_DIRECTION (face->d));
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_face_reset_normal_velocity:
+ * @face: a #FttCellFace.
+ *
+ * Set velocity normal to @face to zero.
+ */
+void gfs_face_reset_normal_velocity (const FttCellFace * face)
+{
+  g_return_if_fail (face != NULL);
+
+  GFS_FACE_NORMAL_VELOCITY_RIGHT (face) = 
+    GFS_FACE_NORMAL_VELOCITY_LEFT (face) = 0.;
+}
+
+/**
+ * gfs_cell_is_small:
+ * @cell: a #FttCell.
+ *
+ * Returns: %TRUE if @cell is "small" (i.e. should be merged with a neighbhor).
+ */
+gboolean gfs_cell_is_small (const FttCell * cell)
+{
+  g_return_val_if_fail (cell != NULL, FALSE);
+
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+  if (solid) {
+    FttDirection d;
+    FttCellNeighbors n;
+
+    ftt_cell_neighbors (cell, &n);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (n.c[d] && !GFS_CELL_IS_BOUNDARY (n.c[d]) && solid->s[d] > 0. && 
+	  solid->a/solid->s[d] < GFS_SMALL)
+	return TRUE;
+  }
+  return FALSE;
+}
+
+static void set_merged (FttCell * cell)
+{
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+  if (!gfs_cell_is_small (cell))
+    solid->merged = NULL;
+  else {
+    FttCellNeighbors neighbor;
+    gdouble abest = 0.;
+    FttDirection i;
+
+    ftt_cell_neighbors (cell, &neighbor);
+    for (i = 0; i < FTT_NEIGHBORS && abest < 1.; i++)
+      if (neighbor.c[i] && !GFS_CELL_IS_BOUNDARY (neighbor.c[i]) && solid->s[i] > 0.) {
+	if (FTT_CELL_IS_LEAF (neighbor.c[i])) {
+	  if (GFS_IS_MIXED (neighbor.c[i])) {
+	    gdouble a = GFS_STATE (neighbor.c[i])->solid->a;
+	    
+	    if (a > abest) {
+	      abest = a;
+	      solid->merged = neighbor.c[i];
+	    }
+	  }
+	  else {
+	    solid->merged = neighbor.c[i];
+	    return;
+	  }
+	}
+	else {
+	  FttCellChildren child;
+	  guint j, n = ftt_cell_children_direction (neighbor.c[i], FTT_OPPOSITE_DIRECTION (i), &child);
+
+	  for (j = 0; j < n; j++)
+	    if (child.c[j]) {
+	      if (GFS_IS_MIXED (child.c[j])) {
+		gdouble a = GFS_STATE (child.c[j])->solid->a;
+	    
+		if (a > abest) {
+		  abest = a;
+		  solid->merged = child.c[j];
+		}
+	      }
+	      else {
+		solid->merged = child.c[j];
+		return;
+	      }
+	    }
+	}
+      }
+    if (abest == 0.)
+      g_warning ("file %s: line %d (%s): cannot merge small cell: %g",
+		 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		 solid->a);
+  }
+}
+
+/**
+ * gfs_set_merged:
+ * @domain: the domain to traverse.
+ *
+ * Sets the @merged field of the mixed cells of the domain defined
+ * by @domain. 
+ */
+void gfs_set_merged (GfsDomain * domain)
+{
+  g_return_if_fail (domain != NULL);
+
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseFunc) set_merged, NULL);
+}
+
+static void add_merged (GSList ** merged, FttCell * cell)
+{
+  if ((cell->flags & GFS_FLAG_USED) == 0) {
+    FttCellNeighbors neighbor;
+    FttDirection i;
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+    *merged = g_slist_prepend (*merged, cell);
+    cell->flags |= GFS_FLAG_USED;
+
+    if (solid && solid->merged)
+      add_merged (merged, solid->merged);
+
+    ftt_cell_neighbors (cell, &neighbor);
+    for (i = 0; i < FTT_NEIGHBORS; i++)
+      if (neighbor.c[i]) {
+	if (!FTT_CELL_IS_LEAF (neighbor.c[i])) {
+	  FttCellChildren child;
+	  guint j, n;
+
+	  n = ftt_cell_children_direction (neighbor.c[i], FTT_OPPOSITE_DIRECTION (i), &child);;
+	  for (j = 0; j < n; j++)
+	    if (GFS_IS_MIXED (child.c[j]) &&
+		GFS_STATE (child.c[j])->solid->merged == cell)
+	      add_merged (merged, child.c[j]);
+	}
+	else if (GFS_IS_MIXED (neighbor.c[i]) && 
+		 GFS_STATE (neighbor.c[i])->solid->merged == cell)
+	  add_merged (merged, neighbor.c[i]);
+      }
+  }
+}
+
+static void traverse_merged (FttCell * cell, gpointer * datum)
+{
+  if ((cell->flags & GFS_FLAG_USED) == 0) {
+    GfsMergedTraverseFunc func = (GfsMergedTraverseFunc) datum[0];
+    gpointer data = datum[1];
+    GSList * merged = NULL;
+
+    add_merged (&merged, cell);
+    (* func) (merged, data);
+    g_slist_free (merged);
+  }
+}
+
+static void traverse_non_merged (FttCell * cell, gpointer * datum)
+{
+  if ((cell->flags & GFS_FLAG_USED) != 0)
+    cell->flags &= ~GFS_FLAG_USED;
+  else {
+    GfsMergedTraverseFunc func = (GfsMergedTraverseFunc) datum[0];
+    gpointer data = datum[1];
+    GSList merged;
+    merged.data = cell;
+    merged.next = NULL;
+    (* func) (&merged, data);
+  }
+}
+
+/**
+ * gfs_domain_traverse_merged:
+ * @domain: the domain to traverse.
+ * @func: the function to call for each visited merged cells.
+ * @data: user data to pass to @func.
+ *
+ * Traverses the merged leaf cells of the domain defined by @domain. A
+ * list of merged cells is passed to @func. No cell belongs to more
+ * than one merged list.  
+ */
+void gfs_domain_traverse_merged (GfsDomain * domain,
+				GfsMergedTraverseFunc func,
+				gpointer data)
+{
+  gpointer datum[2];
+  
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (func != NULL);
+
+  datum[0] = func;
+  datum[1] = data;
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			    (FttCellTraverseFunc) traverse_merged, datum);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			   (FttCellTraverseFunc) traverse_non_merged, datum);
+}
+
+/**
+ * gfs_advection_update:
+ * @merged: a list of merged #FttCell.
+ * @par: the advection parameters.
+ *
+ * Updates the @v variable of @par for the merged cells of @merged
+ * using the @fv update of each merged cell.
+ *
+ * The @v variable in each cell of the @merged list is set to its
+ * average updated value over the composite cell defined by all the
+ * cells in @merged.  
+ */
+void gfs_advection_update (GSList * merged, const GfsAdvectionParams * par)
+{
+  g_return_if_fail (merged != NULL);
+  g_return_if_fail (par != NULL);
+
+  if (merged->next == NULL) { /* cell is not merged */
+    FttCell * cell = merged->data;
+
+    g_assert (!gfs_cell_is_small (cell));
+
+#if 0 /* D. Calhoun approach (fixme: does not use gfs_domain_cell_fraction()) */
+    if (GFS_IS_MIXED (cell)) {
+      FttDirection d;
+      gdouble mins = G_MAXDOUBLE;
+      GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+      for (d = 0; d < FTT_NEIGHBORS; d++)
+	if (solid->s[d] > 0. && 1./solid->s[d] < mins)
+	  mins = 1./solid->s[d];
+#if 0
+fprintf (stderr, "%g %g %g\n",
+	 solid->a, mins, 
+	 GFS_VALUE (cell, par->fv)/(mins*solid->a));
+#endif
+      if (mins*solid->a > 0.01)
+	GFS_VALUE (cell, par->v) += GFS_VALUE (cell, par->fv)/(mins*solid->a);
+      else
+	GFS_VALUE (cell, par->v) += 100.*GFS_VALUE (cell, par->fv);
+      g_assert (GFS_VALUE (cell, par->v) < 10.);
+    }
+    else
+#endif
+
+      GFS_VALUE (cell, par->v) +=
+	GFS_VALUE (cell, par->fv)/gfs_domain_cell_fraction (par->v->domain, cell);
+  }
+  else if (par->average) {
+    /* average value */
+    GSList * i = merged;
+    gdouble w = 0., total_vol = 0.;
+
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble vol = ftt_cell_volume (cell);
+      gdouble a = gfs_domain_cell_fraction (par->v->domain, cell);
+      
+      total_vol += vol*a;
+      w += vol*(a*GFS_VALUE (cell, par->v) + GFS_VALUE (cell, par->fv));
+      i = i->next;
+    }
+    w /= total_vol;
+
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+
+      GFS_VALUE (cell, par->v) = w;
+      i = i->next;
+    }
+  }
+  else {
+    GSList * i = merged;
+    gdouble w = 0., total_vol = 0.;
+
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble vol = ftt_cell_volume (cell);
+      gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+      gdouble f = gfs_domain_cell_fraction (par->v->domain, cell);
+
+      total_vol += vol*f;
+      if (a < GFS_SMALL) {
+	GFS_VALUE (cell, par->v) += GFS_VALUE (cell, par->fv)/(GFS_SMALL*f/a);
+	w += vol*GFS_VALUE (cell, par->fv)*(1. - a/GFS_SMALL);
+      }
+      else
+	GFS_VALUE (cell, par->v) += GFS_VALUE (cell, par->fv)/f;
+
+      i = i->next;
+    }
+    w /= total_vol;
+
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+      /* fixme: small cells should be excluded here?? 
+	 (with corresponding modification in total_vol) */
+      GFS_VALUE (cell, par->v) += w;
+      i = i->next;
+    }
+  }
+}
+
+void gfs_advection_params_write (GfsAdvectionParams * par, FILE * fp)
+{
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp,
+           "{\n"
+	   "  cfl      = %g\n"
+	   "  gradient = %s\n"
+	   "  flux     = %s\n"
+	   "  average  = %d\n",
+	   par->cfl,
+	   par->gradient == gfs_center_gradient ? 
+	   "gfs_center_gradient" :
+	   par->gradient == gfs_center_van_leer_gradient ?
+	   "gfs_center_van_leer_gradient" :
+	   par->gradient == gfs_center_minmod_gradient ?
+	   "gfs_center_minmod_gradient" :
+	   "none",
+	   par->flux == gfs_face_advection_flux ?
+	   "gfs_face_advection_flux" :
+	   par->flux == gfs_face_velocity_advection_flux ?
+	   "gfs_face_velocity_advection_flux" :
+	   par->flux == gfs_face_velocity_convective_flux ?
+	   "gfs_face_velocity_convective_flux" : "NULL",
+	   par->average);
+  if (par->gc)
+    fputs ("  gc       = 1\n", fp);
+  switch (par->scheme) {
+  case GFS_GODUNOV: fputs ("  scheme   = godunov\n", fp); break;
+  case GFS_NONE:    fputs ("  scheme   = none\n", fp); break;
+  }
+  if (par->moving_order != 1)
+    fputs ("  moving_order = 2\n", fp);
+  fputc ('}', fp);
+}
+
+void gfs_advection_params_init (GfsAdvectionParams * par)
+{
+  g_return_if_fail (par != NULL);
+
+  par->fv = NULL;
+  par->u = NULL;
+  par->g = NULL;
+  par->cfl = 0.8;
+  par->dt = 0.;
+  par->gradient = gfs_center_gradient;
+  par->upwinding = GFS_FACE_UPWINDING;
+  par->use_centered_velocity = TRUE;
+  par->scheme = GFS_GODUNOV;
+  par->average = FALSE;
+  par->gc = FALSE;
+  par->update = (GfsMergedTraverseFunc) gfs_advection_update;
+  par->moving_order = 1;
+}
+
+static gdouble none (FttCell * cell, FttComponent c, guint v)
+{
+  return 0.;
+}
+
+void gfs_advection_params_read (GfsAdvectionParams * par, GtsFile * fp)
+{
+  GtsFileVariable var[] = {
+    {GTS_DOUBLE, "cfl",          TRUE},
+    {GTS_STRING, "gradient",     TRUE},
+    {GTS_STRING, "flux",         TRUE},
+    {GTS_STRING, "scheme",       TRUE},
+    {GTS_INT,    "average",      TRUE},
+    {GTS_INT,    "gc",           TRUE},
+    {GTS_UINT,   "moving_order", TRUE},
+    {GTS_NONE}
+  };
+  gchar * gradient = NULL, * flux = NULL, * scheme = NULL;
+
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (fp != NULL);
+
+  var[0].data = &par->cfl;
+  var[1].data = &gradient;
+  var[2].data = &flux;
+  var[3].data = &scheme;
+  var[4].data = &par->average;
+  var[5].data = &par->gc;
+  var[6].data = &par->moving_order;
+
+  gts_file_assign_variables (fp, var);
+
+  if (fp->type != GTS_ERROR && par->cfl <= 0.)
+    gts_file_variable_error (fp, var, "cfl", "cfl must be strictly positive");
+
+  if (gradient) {
+    if (!strcmp (gradient, "gfs_center_gradient"))
+      par->gradient = gfs_center_gradient;
+    else if (!strcmp (gradient, "gfs_center_van_leer_gradient"))
+      par->gradient = gfs_center_van_leer_gradient;
+    else if (!strcmp (gradient, "gfs_center_minmod_gradient"))
+      par->gradient = gfs_center_minmod_gradient;
+    else if (!strcmp (gradient, "none"))
+      par->gradient = none;
+    else if (fp->type != GTS_ERROR)
+      gts_file_variable_error (fp, var, "gradient",
+			       "unknown gradient parameter `%s'", gradient);
+    g_free (gradient);
+  }
+
+  if (flux) {
+    if (!strcmp (flux, "gfs_face_advection_flux"))
+      par->flux = gfs_face_advection_flux;
+    else if (!strcmp (flux, "gfs_face_velocity_advection_flux"))
+      par->flux = gfs_face_velocity_advection_flux;
+    else if (!strcmp (flux, "gfs_face_velocity_convective_flux"))
+      par->flux = gfs_face_velocity_convective_flux;
+    else if (!strcmp (flux, "NULL"))
+      par->flux = gfs_face_advection_flux;
+    else if (fp->type != GTS_ERROR)
+      gts_file_variable_error (fp, var, "flux",
+			       "unknown flux parameter `%s'", flux);
+    g_free (flux);
+  }
+
+  if (scheme) {
+    if (!strcmp (scheme, "godunov"))
+      par->scheme = GFS_GODUNOV;
+    else if (!strcmp (scheme, "none"))
+      par->scheme = GFS_NONE;
+    else if (fp->type != GTS_ERROR)
+      gts_file_variable_error (fp, var, "scheme",
+			       "unknown scheme parameter `%s'", scheme);
+    g_free (scheme);
+  }
+}
diff --git a/src/advection.h b/src/advection.h
new file mode 100644
index 0000000..a8ce14e
--- /dev/null
+++ b/src/advection.h
@@ -0,0 +1,97 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __ADVECTION_H__
+#define __ADVECTION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "domain.h"
+
+#define GFS_SMALL 0.5
+
+typedef enum {
+  GFS_GODUNOV,
+  GFS_NONE
+} GfsAdvectionScheme;
+
+typedef enum {
+  GFS_CENTERED_UPWINDING,
+  GFS_FACE_UPWINDING,
+  GFS_NO_UPWINDING,
+} GfsUpwinding;
+
+typedef struct _GfsAdvectionParams GfsAdvectionParams;
+typedef
+void      (* GfsFaceAdvectionFluxFunc)       (const FttCellFace * face,
+					      const GfsAdvectionParams * par);
+typedef void (* GfsMergedTraverseFunc)       (GSList * merged,
+					      gpointer data);
+
+struct _GfsAdvectionParams {
+  gdouble cfl, dt;
+  GfsVariable * v, * fv, ** u, ** g;
+  GfsCenterGradient gradient;
+  gboolean use_centered_velocity;
+  GfsUpwinding upwinding;
+  GfsFaceAdvectionFluxFunc flux;
+  GfsAdvectionScheme scheme;
+  gboolean average, gc;
+  GfsMergedTraverseFunc update;
+  guint moving_order;
+};
+
+void         gfs_advection_params_init        (GfsAdvectionParams * par);
+void         gfs_advection_params_write       (GfsAdvectionParams * par, 
+					       FILE * fp);
+void         gfs_advection_params_read        (GfsAdvectionParams * par, 
+					       GtsFile * fp);
+void         gfs_cell_advected_face_values    (FttCell * cell,
+					       const GfsAdvectionParams * par);
+void         gfs_cell_non_advected_face_values (FttCell * cell,
+						const GfsAdvectionParams * par);
+gdouble      gfs_face_upwinded_value          (const FttCellFace * face,
+					       GfsUpwinding upwinding,
+					       GfsVariable ** u);
+void         gfs_face_advection_flux          (const FttCellFace * face,
+					       const GfsAdvectionParams * par);
+void         gfs_face_velocity_advection_flux (const FttCellFace * face,
+					       const GfsAdvectionParams * par);
+void         gfs_face_velocity_convective_flux (const FttCellFace * face,
+						const GfsAdvectionParams * par);
+void         gfs_face_advected_normal_velocity     (const FttCellFace * face,
+						    const GfsAdvectionParams * par);
+void         gfs_face_interpolated_normal_velocity (const FttCellFace * face,
+						    GfsVariable ** v);
+void         gfs_face_reset_normal_velocity        (const FttCellFace * face);
+gboolean     gfs_cell_is_small                     (const FttCell * cell);
+void         gfs_set_merged                        (GfsDomain * domain);
+void         gfs_domain_traverse_merged            (GfsDomain * domain,
+						    GfsMergedTraverseFunc func,
+						    gpointer data);
+void         gfs_advection_update                  (GSList * merged, 
+					            const GfsAdvectionParams * par);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __ADVECTION_H__ */
diff --git a/src/balance.c b/src/balance.c
new file mode 100644
index 0000000..1c54cdc
--- /dev/null
+++ b/src/balance.c
@@ -0,0 +1,323 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "balance.h"
+#include "mpi_boundary.h"
+#include "adaptive.h"
+
+/* GfsEventBalance: Object */
+
+#ifdef HAVE_MPI
+
+static void find_neighbors (GfsBox * box, GArray * pe)
+{
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      guint process = GFS_BOUNDARY_MPI (box->neighbor[d])->process;
+      gboolean found = FALSE;
+      gint i;
+      for (i = 0; i < pe->len && !found; i++)
+	if (g_array_index (pe, guint, i) == process)
+	  found = TRUE;
+      if (!found)
+	g_array_append_val (pe, process);
+    }      
+}
+
+static GArray * neighboring_processors (GfsDomain * domain)
+{
+  GArray * pe = g_array_new (FALSE, FALSE, sizeof (guint));
+  if (domain->pid >= 0)
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) find_neighbors, pe);
+  return pe;
+}
+
+static void count (FttCell * cell, int * n)
+{
+  (*n)++;
+}
+
+#define NITERMAX 100
+#define TOL 0.001
+
+typedef struct {
+  guint * pid;     /* pid of neighbors */
+  gdouble * flow;  /* flow to neighbors */
+  guint n;         /* number of neighbors */
+} BalancingFlow;
+
+/*
+ * Computes the "balancing flow" necessary to balance the domain
+ * sizes on all the processes. @average is the average domain size
+ * (i.e. the target domain size).
+ */
+static BalancingFlow * balancing_flow_new (GfsDomain * domain, int average)
+{
+  BalancingFlow * b;
+
+  b = g_malloc0 (sizeof (BalancingFlow));
+  GArray * pe = neighboring_processors (domain);
+  if (pe->len == 0) {
+    g_array_free (pe, TRUE);
+    return b;
+  }
+  int size = 0, i;
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) count, &size);
+  gdouble rsize = size - average;
+  gdouble * lambda = g_malloc (sizeof (gdouble)*(pe->len + 1)), lambda1, eps = G_MAXDOUBLE;
+  MPI_Request * request = g_malloc (sizeof (MPI_Request)*pe->len);
+  lambda1 = 0.;
+  /* this is Gamma and s from the "double-loop" fix of Johnson,
+     Bickson and Dolev, 2009, equation (6) */
+  gdouble Gamma = 0.5*pe->len, s = 0.5;
+  gdouble tolerance = MAX (TOL*average, 1.);
+  int niter = NITERMAX;
+  while (niter-- && eps > tolerance) {
+    MPI_Status status;
+    /* Send lambda to all neighbors */
+    lambda[0] = lambda1;
+    for (i = 0; i < pe->len; i++)
+      MPI_Isend (&(lambda[0]), 1, MPI_DOUBLE, g_array_index (pe, guint , i), 
+		 domain->pid,
+		 MPI_COMM_WORLD,
+		 &(request[i]));
+    /* Do one iteration of the "double-loop"-fixed Jacobi method for
+       the (graph)-Poisson equation */
+    gdouble rhs = rsize;
+    for (i = 0; i < pe->len; i++) {
+      MPI_Recv (&(lambda[i + 1]), 1, MPI_DOUBLE, g_array_index (pe, guint , i), 
+		g_array_index (pe, guint , i),
+		MPI_COMM_WORLD, &status);
+      rhs += lambda[i + 1];
+    }
+    /* update RHS and lambda for "double-loop"-fix */
+    rsize = (1. - s)*rsize + s*(size - average + Gamma*lambda[0]);
+    lambda1 = rhs/(Gamma + pe->len);
+    eps = fabs (lambda[0] - lambda1);
+    /* synchronize */
+    for (i = 0; i < pe->len; i++)
+      MPI_Wait (&request[i], &status);
+    gfs_all_reduce (domain, eps, MPI_DOUBLE, MPI_MAX);
+  }
+  g_free (request);
+  if (niter < 0 && domain->pid == 0)
+    g_warning ("balancing_flow(): could not converge after %d iterations", NITERMAX);
+
+  b->n = pe->len;
+  lambda1 = lambda[0];
+  for (i = 0; i < b->n; i++)
+    lambda[i] = lambda1 - lambda[i + 1];
+  b->flow = lambda;
+  b->pid = (guint *) g_array_free (pe, FALSE);
+  return b;
+}
+
+static void balancing_flow_destroy (BalancingFlow * b)
+{
+  g_free (b->pid);
+  g_free (b->flow);
+  g_free (b);
+}
+
+static void reset_box_size (GfsBox * box)
+{
+  box->size = 0;
+}
+
+typedef struct {
+  GfsBox * box;
+  gint dest, flow, min, neighboring;
+} BoxData;
+
+static void select_neighbouring_box (GfsBox * box, BoxData * b)
+{
+  if (box->pid != b->dest) {
+    gint neighboring = 0;
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if ((GFS_IS_BOUNDARY_MPI (box->neighbor[d]) &&
+	   GFS_BOUNDARY_MPI (box->neighbor[d])->process == b->dest) ||
+	  (GFS_IS_BOX (box->neighbor[d]) &&
+	   GFS_BOX (box->neighbor[d])->pid == b->dest))
+	neighboring++;
+
+    if (neighboring && neighboring >= b->neighboring) {
+      if (box->size == 0)
+	ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			   (FttCellTraverseFunc) count, &box->size);
+      if (neighboring > b->neighboring ||
+	  fabs (box->size - b->flow) < fabs (b->box->size - b->flow)) {
+	b->box = box;
+	b->neighboring = neighboring;
+      }
+    }
+  }
+}
+
+static void get_pid (GfsBox * box, GArray * pid)
+{
+  g_assert (box->id > 0 && box->id <= pid->len);
+  g_array_index (pid, guint, box->id - 1) = gfs_box_domain (box)->pid;
+}
+
+static void update_box_pid (GfsBox * box, GArray * pid)
+{
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      guint id = GFS_BOUNDARY_MPI (box->neighbor[d])->id;
+      g_assert (id > 0 && id <= pid->len);
+      GFS_BOUNDARY_MPI (box->neighbor[d])->process = g_array_index (pid, guint, id - 1);
+    }
+}
+
+#endif /* HAVE_MPI */
+
+static void gfs_event_balance_write (GtsObject * o, FILE * fp)
+{
+  GfsEventBalance * s = GFS_EVENT_BALANCE (o);
+
+  if (GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class->write)
+      (o, fp);
+
+  fprintf (fp, " %g", s->max);
+}
+
+static void gfs_event_balance_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventBalance * s = GFS_EVENT_BALANCE (*o);
+  GfsDomain * domain =  GFS_DOMAIN (gfs_object_simulation (s));
+
+  if (GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  
+  s->max = gfs_read_constant (fp, domain);
+}
+
+static gboolean gfs_event_balance_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_balance_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsEventBalance * s = GFS_EVENT_BALANCE (event);
+    GtsRange size, boundary, mpiwait;
+
+    gfs_domain_stats_balance (domain, &size, &boundary, &mpiwait);
+    if (size.max/size.min > 1. + s->max) {
+#ifdef HAVE_MPI
+      BalancingFlow * balance = balancing_flow_new (domain, size.mean);
+      GPtrArray * request = g_ptr_array_new ();
+      int modified = FALSE;
+      int i;
+      /* Send boxes */
+      gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) reset_box_size, NULL);
+      guint nb = gts_container_size (GTS_CONTAINER (domain));
+      for (i = 0; i < balance->n; i++)
+	if (balance->flow[i] > 0.) { /* largest subdomain */
+	  /* we need to find the list of boxes which minimizes 
+	     |\sum n_i - n| where n_i is the size of box i. This is known in
+	     combinatorial optimisation as a "knapsack problem". */
+	  GSList * l = NULL;
+	  BoxData b;
+	  b.flow = balance->flow[i];
+	  b.dest = balance->pid[i];
+	  while (b.flow > 0 && nb > 1) {
+	    b.box = NULL; b.neighboring = 0;
+	    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) select_neighbouring_box, &b);
+	    if (b.box && b.box->size <= 2*b.flow) {
+	      l = g_slist_prepend (l, b.box);
+	      b.box->pid = b.dest;
+	      b.flow -= b.box->size;
+	      nb--;
+	      modified = TRUE;
+	    }
+	    else
+	      b.flow = 0;
+	  }
+	  g_ptr_array_add (request, gfs_send_boxes (domain, l, balance->pid[i]));
+	  g_slist_free (l);
+	}
+      /* Receive boxes */
+      for (i = 0; i < balance->n; i++)
+	if (balance->flow[i] < 0.) { /* smallest subdomain */
+	  GSList * l = gfs_receive_boxes (domain, balance->pid[i]);
+	  g_slist_free (l);
+	}
+      /* Synchronize */
+      for (i = 0; i < request->len; i++)
+	gfs_wait (g_ptr_array_index (request, i));
+      g_ptr_array_free (request, TRUE);
+      balancing_flow_destroy (balance);
+      /* Reshape */
+      gfs_all_reduce (domain, modified, MPI_INT, MPI_MAX);
+      if (modified) {
+	/* Updates the pid associated with each box */
+	guint nb = gts_container_size (GTS_CONTAINER (domain));
+	gfs_all_reduce (domain, nb, MPI_UNSIGNED, MPI_SUM);
+	GArray * pid = g_array_sized_new (FALSE, TRUE, sizeof (guint), nb);
+	g_array_set_size (pid, nb);
+	gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) get_pid, pid);
+	MPI_Allreduce (MPI_IN_PLACE, pid->data, nb, MPI_UNSIGNED, MPI_MAX, MPI_COMM_WORLD);
+	/* pid[id] now contains the current pid of box with index id */
+	gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) update_box_pid, pid);
+	g_array_free (pid, TRUE);
+	gfs_domain_reshape (domain, gfs_domain_depth (domain));
+      }
+#else /* not HAVE_MPI */
+      g_assert_not_reached ();
+#endif /* not HAVE_MPI */
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_balance_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_balance_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_balance_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_balance_event;
+}
+
+GfsEventClass * gfs_event_balance_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_balance_info = {
+      "GfsEventBalance",
+      sizeof (GfsEventBalance),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_balance_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_balance_info);
+  }
+
+  return klass;
+}
diff --git a/src/balance.h b/src/balance.h
new file mode 100644
index 0000000..2f5281f
--- /dev/null
+++ b/src/balance.h
@@ -0,0 +1,51 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __BALANCE_H__
+#define __BALANCE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "event.h"
+
+/* GfsEventBalance: Header */
+
+typedef struct _GfsEventBalance         GfsEventBalance;
+
+struct _GfsEventBalance {
+  GfsEvent parent;
+
+  gdouble max;
+};
+
+#define GFS_EVENT_BALANCE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventBalance,\
+					         gfs_event_balance_class ())
+#define GFS_IS_EVENT_BALANCE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_balance_class ()))
+
+GfsEventClass * gfs_event_balance_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BALANCE_H__ */
diff --git a/src/boundary.c b/src/boundary.c
new file mode 100644
index 0000000..26306b0
--- /dev/null
+++ b/src/boundary.c
@@ -0,0 +1,1867 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "config.h"
+#include "boundary.h"
+#include "simulation.h"
+#include "adaptive.h"
+#include "vof.h"
+
+static FttVector rpos[FTT_NEIGHBORS] = {
+#if FTT_2D
+  {1.,0.,0.}, {-1.,0.,0.}, {0.,1.,0.}, {0.,-1.,0.}
+#else  /* FTT_3D */
+  {1.,0.,0.}, {-1.,0.,0.}, {0.,1.,0.}, {0.,-1.,0.}, {0.,0.,1.}, {0.,0.,-1.}
+#endif /* FTT_3D */
+};
+
+/* GfsBc: Object */
+
+static void symmetry (FttCellFace * f, GfsBc * b)
+{
+  if (b->v->component == f->d/2)
+    GFS_VARIABLE (f->cell, b->v->i) = - GFS_VARIABLE (f->neighbor, b->v->i);
+  else
+    GFS_VARIABLE (f->cell, b->v->i) =   GFS_VARIABLE (f->neighbor, b->v->i);
+}
+
+static void face_symmetry (FttCellFace * f, GfsBc * b)
+{
+  if (b->v->component == f->d/2)
+    GFS_STATE (f->cell)->f[f->d].v = 
+      GFS_STATE (f->neighbor)->f[FTT_OPPOSITE_DIRECTION (f->d)].v = 0.;
+  else if (GFS_IS_VARIABLE_TRACER_VOF (b->v))
+    GFS_STATE (f->cell)->f[f->d].v = GFS_VARIABLE (f->neighbor, b->v->i);
+  else
+    GFS_STATE (f->cell)->f[f->d].v = 
+      GFS_STATE (f->neighbor)->f[FTT_OPPOSITE_DIRECTION (f->d)].v;
+}
+
+static void bc_write (GtsObject * o, FILE * fp)
+{
+  g_assert (GFS_BC (o)->v);
+  fprintf (fp, "%s %s", o->klass->info.name, GFS_BC (o)->v->name);
+}
+
+static void bc_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBc * bc = GFS_BC (*o);
+
+  g_assert (bc->b);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (klass)");
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (v)");
+    return;
+  }
+  bc->v = gfs_variable_from_name (gfs_box_domain (bc->b->box)->variables, 
+				  fp->token->str);
+  if (bc->v == NULL)
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+  else
+    gts_file_next_token (fp);
+}
+
+static void gfs_bc_class_init (GtsObjectClass * klass)
+{
+  klass->write = bc_write;
+  klass->read =  bc_read;
+}
+
+static void gfs_bc_init (GfsBc * object)
+{
+  object->bc =             (FttFaceTraverseFunc) symmetry;
+  object->homogeneous_bc = (FttFaceTraverseFunc) symmetry;
+  object->face_bc =        (FttFaceTraverseFunc) face_symmetry;
+}
+
+GfsBcClass * gfs_bc_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_info = {
+      "GfsBc",
+      sizeof (GfsBc),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_class_init,
+      (GtsObjectInitFunc) gfs_bc_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_bc_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_bc_new:
+ * @k: a #GfsBcClass.
+ * @v: a variable associated with the BC or %NULL.
+ * @extra:
+ *
+ * Returns: a new #GfsBc.
+ */
+GfsBc * gfs_bc_new (GfsBcClass * k, GfsVariable * v, gboolean extra)
+{
+  GfsBc * b;
+
+  g_return_val_if_fail (k != NULL, NULL);
+
+  b = GFS_BC (gts_object_new (GTS_OBJECT_CLASS (k)));
+  if (v)
+    gfs_object_simulation_set (b, v->domain);
+  b->v = v;
+  b->extra = extra;
+
+  return b;
+}
+
+/* GfsBcValue: Object */
+
+static void bc_value_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_bc_value_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_bc_value_class ())->parent_class->write) 
+      (o, fp);
+  if (GFS_BC_VALUE (o)->val)
+    gfs_function_write (GFS_BC_VALUE (o)->val, fp);
+}
+
+static void bc_value_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBcValue * bc = GFS_BC_VALUE (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_bc_value_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_bc_value_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (bc->val == NULL)
+    bc->val = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_read (GFS_BC_VALUE (*o)->val, gfs_box_domain (GFS_BC (bc)->b->box), fp);
+}
+
+static void bc_value_destroy (GtsObject * o)
+{
+  if (GFS_BC_VALUE (o)->val)
+    gts_object_destroy (GTS_OBJECT (GFS_BC_VALUE (o)->val));
+
+  (* GTS_OBJECT_CLASS (gfs_bc_value_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_bc_value_class_init (GtsObjectClass * klass)
+{
+  klass->write   = bc_value_write;
+  klass->read    = bc_value_read;
+  klass->destroy = bc_value_destroy;
+}
+
+GfsBcClass * gfs_bc_value_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_value_info = {
+      "GfsBcValue",
+      sizeof (GfsBcValue),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_value_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_class ()),
+				  &gfs_bc_value_info);
+  }
+
+  return klass;
+}
+
+static GfsBc * gfs_bc_value_new (GfsBcClass * k,
+				 GfsVariable * v,
+				 GfsFunction * val,
+				 gboolean extra)
+{
+  GfsBcValue * bc = GFS_BC_VALUE (gfs_bc_new (k, v, extra));
+
+  if (val == NULL)
+    bc->val = gfs_function_new (gfs_function_class (), 0.);
+  else
+    bc->val = val;
+
+  return GFS_BC (bc);
+}
+
+/* GfsBcDirichlet: Object */
+
+static void dirichlet (FttCellFace * f, GfsBc * b)
+{
+  GFS_VALUE (f->cell, b->v) = 
+    2.*gfs_function_face_value (GFS_BC_VALUE (b)->val, f)
+    - GFS_VALUE (f->neighbor, b->v);
+}
+
+static void dirichlet_vof (FttCellFace * f, GfsBc * b)
+{
+  GFS_VALUE (f->cell, b->v) = gfs_function_face_value (GFS_BC_VALUE (b)->val, f);
+}
+
+static void homogeneous_dirichlet (FttCellFace * f, GfsBc * b)
+{
+  GFS_VALUE (f->cell, b->v) = - GFS_VALUE (f->neighbor, b->v);
+}
+
+static void face_dirichlet (FttCellFace * f, GfsBc * b)
+{
+  GFS_STATE (f->cell)->f[f->d].v = GFS_STATE (f->neighbor)->f[FTT_OPPOSITE_DIRECTION (f->d)].v = 
+    gfs_function_face_value (GFS_BC_VALUE (b)->val, f);
+}
+
+static void bc_dirichlet_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBc * bc = GFS_BC (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_bc_dirichlet_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_bc_dirichlet_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_function_set_units (GFS_BC_VALUE (bc)->val, bc->v->units);
+  if (GFS_IS_VARIABLE_TRACER_VOF (bc->v))
+    bc->bc = (FttFaceTraverseFunc) dirichlet_vof;
+}
+
+static void gfs_bc_dirichlet_init (GfsBc * object)
+{
+  object->bc =             (FttFaceTraverseFunc) dirichlet;
+  object->homogeneous_bc = (FttFaceTraverseFunc) homogeneous_dirichlet;
+  object->face_bc =        (FttFaceTraverseFunc) face_dirichlet;
+}
+
+static void gfs_bc_dirichlet_class_init (GtsObjectClass * klass)
+{
+  klass->read = bc_dirichlet_read;
+}
+
+GfsBcClass * gfs_bc_dirichlet_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_dirichlet_info = {
+      "GfsBcDirichlet",
+      sizeof (GfsBcValue),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_dirichlet_class_init,
+      (GtsObjectInitFunc) gfs_bc_dirichlet_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_dirichlet_info);
+  }
+
+  return klass;
+}
+
+/* GfsBcNeumann: Object */
+
+static void neumann (FttCellFace * f, GfsBc * b)
+{
+  GFS_VALUE (f->cell, b->v) = 
+    GFS_VALUE (f->neighbor, b->v) +
+    gfs_function_face_value (GFS_BC_VALUE (b)->val, f)
+    *ftt_cell_size (f->cell);
+}
+
+static void homogeneous_neumann (FttCellFace * f, GfsBc * b)
+{
+  GFS_VALUE (f->cell, b->v) = GFS_VALUE (f->neighbor, b->v);
+}
+
+static void face_neumann (FttCellFace * f, GfsBc * b)
+{
+  GFS_STATE (f->cell)->f[f->d].v = 
+    GFS_VALUE (f->neighbor, b->v) +
+    gfs_function_face_value (GFS_BC_VALUE (b)->val, f)
+    *ftt_cell_size (f->cell)/2.;
+}
+
+static void bc_neumann_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBc * bc = GFS_BC (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_bc_neumann_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_bc_neumann_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_function_set_units (GFS_BC_VALUE (bc)->val, bc->v->units - 1.);
+}
+
+static void gfs_bc_neumann_init (GfsBc * object)
+{
+  object->bc =             (FttFaceTraverseFunc) neumann;
+  object->homogeneous_bc = (FttFaceTraverseFunc) homogeneous_neumann;
+  object->face_bc =        (FttFaceTraverseFunc) face_neumann;
+}
+
+static void gfs_bc_neumann_class_init (GtsObjectClass * klass)
+{
+  klass->read = bc_neumann_read;
+}
+
+GfsBcClass * gfs_bc_neumann_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_neumann_info = {
+      "GfsBcNeumann",
+      sizeof (GfsBcValue),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_neumann_class_init,
+      (GtsObjectInitFunc) gfs_bc_neumann_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_neumann_info);
+  }
+
+  return klass;
+}
+
+/* GfsBcNavier: Object */
+
+static void navier (FttCellFace * f, GfsBc * b)
+{
+  gdouble h = ftt_cell_size (f->cell);
+  gdouble lambda = gfs_function_face_value (GFS_BC_NAVIER (b)->lambda, f);
+  GFS_VARIABLE (f->cell, b->v->i) = 
+    (2.*gfs_function_face_value (GFS_BC_VALUE (b)->val, f)*h
+     - (h - 2.*lambda)*GFS_VARIABLE (f->neighbor, b->v->i))/(h + 2.*lambda);
+}
+
+static void face_navier (FttCellFace * f, GfsBc * b)
+{
+  gdouble h = ftt_cell_size (f->cell);
+  gdouble lambda = gfs_function_face_value (GFS_BC_NAVIER (b)->lambda, f);
+  GFS_STATE (f->cell)->f[f->d].v = GFS_STATE (f->neighbor)->f[FTT_OPPOSITE_DIRECTION (f->d)].v = 
+    (gfs_function_face_value (GFS_BC_VALUE (b)->val, f)*h + 
+     2.*lambda*GFS_VARIABLE (f->neighbor, b->v->i))/(h + 2.*lambda);
+}
+
+static void bc_navier_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_bc_navier_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_bc_navier_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  GfsBcNavier * bc = GFS_BC_NAVIER (*o);
+  if (bc->lambda == NULL)
+    bc->lambda = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_set_units (bc->lambda, 1.);
+  gfs_function_read (bc->lambda, gfs_box_domain (GFS_BC (bc)->b->box), fp);
+}
+
+static void bc_navier_write (GtsObject * o, FILE * fp)
+{  
+  (* GTS_OBJECT_CLASS (gfs_bc_navier_class ())->parent_class->write) (o, fp);
+  if (GFS_BC_NAVIER (o)->lambda)
+    gfs_function_write (GFS_BC_NAVIER (o)->lambda, fp);
+}
+
+static void gfs_bc_navier_init (GfsBc * object)
+{
+  object->bc =             (FttFaceTraverseFunc) navier;
+  object->homogeneous_bc = (FttFaceTraverseFunc) homogeneous_dirichlet;
+  object->face_bc =        (FttFaceTraverseFunc) face_navier;
+}
+
+static void gfs_bc_navier_class_init (GtsObjectClass * klass)
+{
+  klass->read = bc_navier_read;
+  klass->write = bc_navier_write;
+}
+
+GfsBcClass * gfs_bc_navier_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_navier_info = {
+      "GfsBcNavier",
+      sizeof (GfsBcNavier),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_navier_class_init,
+      (GtsObjectInitFunc) gfs_bc_navier_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_navier_info);
+  }
+
+  return klass;
+}
+
+/* GfsBoundary: Object */
+
+static void destroy_bc (GfsVariable * v, GtsObject * o)
+{
+  gts_object_destroy (o);
+}
+
+static void gfs_boundary_destroy (GtsObject * object)
+{
+  GfsBoundary * boundary = GFS_BOUNDARY (object);
+
+  if (boundary->root) {
+    GfsDomain * domain = gfs_box_domain (boundary->box);
+    if (domain == NULL) /* domain has been destroyed */
+      ftt_cell_destroy (boundary->root, NULL, NULL);
+    else
+      ftt_cell_destroy (boundary->root, (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+  }
+  boundary->box->neighbor[FTT_OPPOSITE_DIRECTION (boundary->d)] = NULL;
+
+  gts_object_destroy (GTS_OBJECT (boundary->default_bc));
+  if (boundary->bc) {
+    g_hash_table_foreach (boundary->bc, (GHFunc) destroy_bc, NULL);
+    g_hash_table_destroy (boundary->bc);
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_boundary_class ())->parent_class->destroy) (object);
+}
+
+static void match (FttCell * cell, GfsBoundary * boundary)
+{
+  FttCell * neighbor = ftt_cell_neighbor (cell, boundary->d);
+  FttCell * parent = ftt_cell_parent (cell);
+  guint level = ftt_cell_level (cell);
+
+  cell->flags |= GFS_FLAG_BOUNDARY;
+  if (parent && GFS_CELL_IS_GRADIENT_BOUNDARY (parent))
+    cell->flags |= GFS_FLAG_GRADIENT_BOUNDARY;
+  if (neighbor == NULL || ftt_cell_level (neighbor) < level) {
+    if (FTT_CELL_IS_ROOT (cell))
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	     "root cell is entirely outside of the fluid domain\n"
+	     "the solid surface orientation may be incorrect");
+    ftt_cell_destroy (cell, (FttCellCleanupFunc) gfs_cell_cleanup, gfs_box_domain (boundary->box));
+    boundary->changed = TRUE;
+    return;
+  }
+  if (ftt_cell_level (neighbor) == level) {
+    GfsSolidVector * s = GFS_STATE (neighbor)->solid;
+
+    if (s && s->s[FTT_OPPOSITE_DIRECTION (boundary->d)] == 0.) {
+      if (FTT_CELL_IS_ROOT (cell))
+	g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	       "root cell is entirely outside of the fluid domain\n"
+	       "the solid surface orientation may be incorrect");
+      ftt_cell_destroy (cell, (FttCellCleanupFunc) gfs_cell_cleanup,
+			gfs_box_domain (boundary->box));
+      boundary->changed = TRUE;
+      return;
+    }
+    if (s) {
+      FttDirection d;
+      FttComponent c;
+      GfsSolidVector * t;
+
+      if (GFS_STATE (cell)->solid == NULL)
+	GFS_STATE (cell)->solid = g_malloc0 (sizeof (GfsSolidVector));
+      t = GFS_STATE (cell)->solid;
+      t->a = s->a;
+      for (d = 0; d < FTT_NEIGHBORS; d++)
+	if (d/2 == boundary->d/2)
+	  t->s[d] = s->s[FTT_OPPOSITE_DIRECTION (d)];
+	else
+	  t->s[d] = s->s[d];
+      for (c = 0; c < FTT_DIMENSION; c++)
+	if (c == boundary->d/2) {
+	  FttVector p1, p2;
+	  ftt_cell_pos (cell, &p1);
+	  ftt_cell_pos (neighbor, &p2);
+	  (&t->cm.x)[c] = (&p1.x)[c] + (&p2.x)[c] - (&s->cm.x)[c];
+	  (&t->ca.x)[c] = (&p1.x)[c] + (&p2.x)[c] - (&s->ca.x)[c];
+	}
+	else {
+	  (&t->cm.x)[c] = (&s->cm.x)[c];
+	  (&t->ca.x)[c] = (&s->ca.x)[c];
+	}
+    }
+    else if (GFS_STATE (cell)->solid != NULL) {
+      g_free (GFS_STATE (cell)->solid);
+      GFS_STATE (cell)->solid = NULL;
+    }      
+    if (FTT_CELL_IS_LEAF (cell) && !FTT_CELL_IS_LEAF (neighbor)) {
+      GfsDomain * domain = gfs_box_domain (boundary->box);
+      ftt_cell_refine_single (cell, domain->cell_init, domain->cell_init_data);
+      boundary->changed = TRUE;
+    }
+  }
+  else
+    g_assert_not_reached ();
+  if (!FTT_CELL_IS_LEAF (cell))
+    level++;
+  if (level > boundary->depth)
+    boundary->depth = level;
+}
+
+static void boundary_match (GfsBoundary * boundary)
+{
+  guint l = ftt_cell_level (boundary->root);
+
+  boundary->changed = FALSE;
+  boundary->depth = l;
+  while (l <= boundary->depth) {
+    ftt_cell_traverse_boundary (boundary->root, boundary->d,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+				(FttCellTraverseFunc) match, boundary);
+    l++;
+  }
+  if (boundary->changed)
+    ftt_cell_flatten (boundary->root, boundary->d, (FttCellCleanupFunc) gfs_cell_cleanup, 
+		      gfs_box_domain (boundary->box));
+}
+
+static void is_extra (GfsVariable * v, GfsBc * bc, gboolean * extra)
+{
+  if (bc->extra)
+    *extra = TRUE;
+}
+
+static void write_extra (GfsVariable * v, GfsBc * bc, FILE * fp)
+{
+  if (bc->extra) {
+    g_assert (GTS_OBJECT (bc)->klass->write);
+    (* GTS_OBJECT (bc)->klass->write) (GTS_OBJECT (bc), fp);
+    fputc ('\n', fp);
+  }
+}
+
+static void gfs_boundary_write (GtsObject * o, FILE * fp)
+{
+  GfsBoundary * b = GFS_BOUNDARY (o);
+  gboolean any_extra = FALSE;
+
+  if (GTS_OBJECT_CLASS (gfs_boundary_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_boundary_class ())->parent_class->write) 
+      (o, fp);
+
+  g_hash_table_foreach (b->bc, (GHFunc) is_extra, &any_extra);
+  if (any_extra) {
+    fputs (" {\n", fp);
+    g_hash_table_foreach (b->bc, (GHFunc) write_extra, fp);
+    fputc ('}', fp);
+  }
+}
+
+static gboolean boundary_read_extra_bc (GfsBoundary * b, GtsFile * fp)
+{
+  gboolean ret = FALSE;
+
+  if (fp->type != '{')
+    return ret;
+
+  fp->scope_max++;
+  gts_file_next_token (fp);
+
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return ret;
+    }
+    else {
+      GtsObjectClass * klass = gfs_object_class_from_name (fp->token->str);
+      GtsObject * object;
+      
+      if (klass == NULL) {
+	gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+	return ret;
+      }
+      else if (!gts_object_class_is_from_class (klass, gfs_bc_class ())) {
+	gts_file_error (fp, "`%s' is not a GfsBc", fp->token->str);
+	return ret;
+      }
+
+      object = gts_object_new (klass);
+      g_assert (klass->read);
+      GFS_BC (object)->b = b;
+      GFS_BC (object)->extra = TRUE;
+      (* klass->read) (&object, fp);
+      if (fp->type == GTS_ERROR) {
+	gts_object_destroy (object);
+	return ret;
+      }
+
+      gfs_boundary_add_bc (b, GFS_BC (object));
+      ret = TRUE;
+    }
+  }
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return ret;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+
+  return ret;
+}
+
+static void gfs_boundary_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_boundary_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_boundary_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  boundary_read_extra_bc (GFS_BOUNDARY (*o), fp);
+}
+
+static void gfs_boundary_class_init (GfsBoundaryClass * klass)
+{
+  klass->match = boundary_match;
+
+  GTS_OBJECT_CLASS (klass)->write =   gfs_boundary_write;
+  GTS_OBJECT_CLASS (klass)->read =    gfs_boundary_read;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_boundary_destroy;
+}
+
+static void gfs_boundary_init (GfsBoundary * b)
+{
+  b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+  b->bc = g_hash_table_new (g_str_hash, g_str_equal);
+  gfs_boundary_set_default_bc (b, gfs_bc_new (gfs_bc_class (), NULL, FALSE));
+}
+
+GfsBoundaryClass * gfs_boundary_class (void)
+{
+  static GfsBoundaryClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_info = {
+      "GfsBoundary",
+      sizeof (GfsBoundary),
+      sizeof (GfsBoundaryClass),
+      (GtsObjectClassInitFunc) gfs_boundary_class_init,
+      (GtsObjectInitFunc) gfs_boundary_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (gts_object_class (), &gfs_boundary_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_boundary_new:
+ * @klass: a #GfsBoundaryClass.
+ * @box: a #GfsBox.
+ * @d: a direction.
+ *
+ * Creates a new boundary of type @klass for @box in direction @d.
+ *
+ * This function fails if @box has already a boundary in direction @d.
+ *
+ * Returns: a new #GfsBoundary.
+ */
+GfsBoundary * gfs_boundary_new (GfsBoundaryClass * klass,
+				GfsBox * box,
+				FttDirection d)
+{
+  GfsBoundary * boundary;
+  GfsDomain * domain;
+  FttVector pos;
+  gdouble size;
+
+  g_return_val_if_fail (box != NULL, NULL);
+  g_return_val_if_fail (d < FTT_NEIGHBORS, NULL);
+  g_return_val_if_fail (box->neighbor[d] == NULL, NULL);
+
+  boundary = GFS_BOUNDARY (gts_object_new (GTS_OBJECT_CLASS (klass)));
+  boundary->box = box;
+  box->neighbor[d] = GTS_OBJECT (boundary);
+  boundary->d = FTT_OPPOSITE_DIRECTION (d);
+  if (box->root) {
+    domain = gfs_box_domain (box);
+    boundary->root = ftt_cell_new ((FttCellInitFunc) gfs_cell_init, domain);
+    FTT_ROOT_CELL (boundary->root)->parent = box;
+    ftt_cell_set_level (boundary->root, ftt_cell_level (box->root));
+    ftt_cell_set_neighbor_match (boundary->root, box->root, boundary->d, 
+				 (FttCellInitFunc) gfs_cell_init, domain);
+    ftt_cell_pos (box->root, &pos);
+    size = ftt_cell_size (box->root);
+    pos.x += rpos[d].x*size;
+    pos.y += rpos[d].y*size;
+    pos.z += rpos[d].z*size;
+    ftt_cell_set_pos (boundary->root, &pos);
+
+    boundary_match (boundary);
+  }
+
+  return boundary;
+}
+
+/**
+ * gfs_boundary_send:
+ * @boundary: a #GfsBoundary.
+ *
+ * Calls the @send() method of @boundary.
+ */
+void gfs_boundary_send (GfsBoundary * boundary)
+{
+  g_return_if_fail (boundary != NULL);
+
+  if (GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->send)
+    (* GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->send) (boundary);
+}
+
+/**
+ * gfs_boundary_receive:
+ * @boundary: a #GfsBoundary.
+ * @flags: the traversal flags.
+ * @max_depth: the maximum depth of the traversal.
+ *
+ * Calls the @receive() method of @boundary.
+ */
+void gfs_boundary_receive (GfsBoundary * boundary,
+			   FttTraverseFlags flags,
+			   gint max_depth)
+{
+  g_return_if_fail (boundary != NULL);
+
+  if (GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->receive)
+    (* GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->receive)
+      (boundary, flags, max_depth);
+}
+
+/**
+ * gfs_boundary_synchronize:
+ * @boundary: a #GfsBoundary.
+ *
+ * Calls the @synchronize() method of @boundary.
+ */
+void gfs_boundary_synchronize (GfsBoundary * boundary)
+{
+  g_return_if_fail (boundary != NULL);
+
+  if (GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->synchronize)
+    (* GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass)->synchronize) (boundary);
+}
+
+/**
+ * gfs_boundary_lookup:
+ * @b: a #GfsBoundary.
+ * @v: a #GfsVariable.
+ *
+ * Returns: the #GfsBc associated with @b and @v.
+ */
+GfsBc * gfs_boundary_lookup_bc (GfsBoundary * b, GfsVariable * v)
+{
+  GfsBc * bv;
+
+  g_return_val_if_fail (b != NULL, NULL);
+  g_return_val_if_fail (v != NULL, NULL);
+
+  if (!v->name || !(bv = g_hash_table_lookup (b->bc, v->name))) {
+    if (v->default_bc) {
+      bv = v->default_bc;
+      bv->b = b;
+    }
+    else
+      bv = b->default_bc;
+    bv->v = v;
+  }
+  return bv;
+}
+
+/**
+ * gfs_boundary_set_default_bc:
+ * @b: a #GfsBoundary.
+ * @bc: a #GfsBc.
+ *
+ * Sets the default boundary condition for @b to @bc.
+ */
+void gfs_boundary_set_default_bc (GfsBoundary * b, GfsBc * bc)
+{
+  g_return_if_fail (b != NULL);
+  g_return_if_fail (bc != NULL);
+  g_return_if_fail (bc->b == NULL || bc->b == b);
+
+  if (b->default_bc)
+    gts_object_destroy (GTS_OBJECT (b->default_bc));
+  b->default_bc = bc;
+  bc->b = b;
+}
+
+/**
+ * gfs_variable_set_default_bc:
+ * @v: a #GfVariable.
+ * @bc: a #GfsBc.
+ *
+ * Sets the default boundary condition for @v to @bc.
+ */
+void gfs_variable_set_default_bc (GfsVariable * v, GfsBc * bc)
+{
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (bc != NULL);
+  g_return_if_fail (bc->v == NULL || bc->v == v);
+
+  if (v->default_bc)
+    gts_object_destroy (GTS_OBJECT (v->default_bc));
+  v->default_bc = bc;
+  bc->v = v;
+}
+
+/**
+ * gfs_boundary_add_bc:
+ * @b: a #GfsBoundary.
+ * @bc: a #GfsBc.
+ *
+ * Adds boundary condition @bc to @b.
+ */
+void gfs_boundary_add_bc (GfsBoundary * b, GfsBc * bc)
+{
+  GfsBc * old;
+  
+  g_return_if_fail (b != NULL);
+  g_return_if_fail (bc != NULL);
+  g_return_if_fail (bc->v != NULL);
+  g_return_if_fail (bc->v->name != NULL);
+  g_return_if_fail (bc->b == NULL || bc->b == b);
+
+  old = g_hash_table_lookup (b->bc, bc->v->name);
+  if (!old || !old->extra) {
+    if (old) gts_object_destroy (GTS_OBJECT (old));
+    g_hash_table_insert (b->bc, bc->v->name, bc);
+    bc->b = b;
+  }
+  else
+    gts_object_destroy (GTS_OBJECT (bc));
+}
+
+/* GfsBoundaryInflowConstant: Object */
+
+static GtsColor inflow_color (GtsObject * o)
+{
+  GtsColor c = { 0., 0., 1. }; /* blue */
+
+  return c;
+}
+
+static void inflow_constant_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_boundary_inflow_constant_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_boundary_inflow_constant_class ())->parent_class->write) 
+      (o, fp);
+
+  gfs_function_write (GFS_BOUNDARY_INFLOW_CONSTANT (o)->un, fp);
+}
+
+static void inflow_constant_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBoundary * b = GFS_BOUNDARY (*o);  
+  FttComponent c;
+  GfsFunction * un = GFS_BOUNDARY_INFLOW_CONSTANT (*o)->un;
+  GfsVariable ** v;
+
+  if (GTS_OBJECT_CLASS (gfs_boundary_inflow_constant_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_boundary_inflow_constant_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_function_read (un, gfs_box_domain (b->box), fp);
+  gfs_function_set_units (un, 1.);
+
+  v = gfs_domain_velocity (gfs_box_domain (b->box));
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (c == b->d/2)
+      gfs_boundary_add_bc (b, gfs_bc_value_new (gfs_bc_dirichlet_class (),
+						v[c], un, FALSE));
+    else
+      gfs_boundary_add_bc (b, gfs_bc_value_new (gfs_bc_dirichlet_class (),
+						v[c], NULL, FALSE));
+}
+
+static void gfs_boundary_inflow_constant_class_init (GtsObjectClass * klass)
+{
+  klass->read    = inflow_constant_read;
+  klass->write   = inflow_constant_write;
+  klass->color   = inflow_color;
+}
+
+static void gfs_boundary_inflow_constant_init (GfsBoundaryInflowConstant * object)
+{
+  object->un = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsBoundaryInflowConstantClass * gfs_boundary_inflow_constant_class (void)
+{
+  static GfsBoundaryInflowConstantClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_inflow_constant_info = {
+      "GfsBoundaryInflowConstant",
+      sizeof (GfsBoundaryInflowConstant),
+      sizeof (GfsBoundaryInflowConstantClass),
+      (GtsObjectClassInitFunc) gfs_boundary_inflow_constant_class_init,
+      (GtsObjectInitFunc) gfs_boundary_inflow_constant_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_boundary_class ()),
+				  &gfs_boundary_inflow_constant_info);
+  }
+
+  return klass;
+}
+
+/* GfsBoundaryOutflow: Object */
+
+static GtsColor outflow_color (GtsObject * o)
+{
+  GtsColor c = { 0., 1., 0. }; /* green */
+
+  return c;
+}
+
+static void outflow_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBoundary * b = GFS_BOUNDARY (*o);
+  GfsDomain * domain;
+  GfsVariable ** v;
+
+  if (GTS_OBJECT_CLASS (gfs_boundary_outflow_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_boundary_outflow_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  domain = gfs_box_domain (b->box);
+  v = gfs_domain_velocity (domain);
+  gfs_boundary_add_bc (b, gfs_bc_value_new (gfs_bc_neumann_class (),
+					    v[b->d/2],
+					    NULL, FALSE));
+  gfs_boundary_add_bc (b, gfs_bc_value_new (gfs_bc_dirichlet_class (),
+					    gfs_variable_from_name (domain->variables, "P"),
+					    NULL, FALSE));
+}
+
+static void gfs_boundary_outflow_class_init (GfsBoundaryClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read   = outflow_read;
+  GTS_OBJECT_CLASS (klass)->color  = outflow_color;
+}
+
+GfsBoundaryOutflowClass * gfs_boundary_outflow_class (void)
+{
+  static GfsBoundaryOutflowClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_outflow_info = {
+      "GfsBoundaryOutflow",
+      sizeof (GfsBoundary),
+      sizeof (GfsBoundaryOutflowClass),
+      (GtsObjectClassInitFunc) gfs_boundary_outflow_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_boundary_class ()),
+				  &gfs_boundary_outflow_info);
+  }
+
+  return klass;
+}
+
+/* GfsBoundaryGradient: Object */
+
+static GtsColor gradient_color (GtsObject * o)
+{
+  GtsColor c = { 1., 1., 0. }; /* red-green */
+
+  return c;
+}
+
+static void set_gradient_boundary (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_GRADIENT_BOUNDARY;
+}
+
+static void gradient_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBoundary * b = GFS_BOUNDARY (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_boundary_gradient_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_boundary_gradient_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  ftt_cell_traverse (b->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) set_gradient_boundary, NULL);
+}
+
+static void gfs_boundary_gradient_class_init (GfsBoundaryClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read   = gradient_read;
+  GTS_OBJECT_CLASS (klass)->color  = gradient_color;
+}
+
+GfsBoundaryClass * gfs_boundary_gradient_class (void)
+{
+  static GfsBoundaryClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_gradient_info = {
+      "GfsBoundaryGradient",
+      sizeof (GfsBoundary),
+      sizeof (GfsBoundaryClass),
+      (GtsObjectClassInitFunc) gfs_boundary_gradient_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_boundary_class ()),
+				  &gfs_boundary_gradient_info);
+  }
+
+  return klass;
+}
+
+/* GfsBoundaryPeriodic: object */
+
+static void boundary_periodic_destroy (GtsObject * object)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (object);
+
+  g_array_free (boundary->sndbuf, TRUE);
+  g_array_free (boundary->rcvbuf, TRUE);
+  
+  (* GTS_OBJECT_CLASS (gfs_boundary_periodic_class ())->parent_class->destroy) 
+    (object);
+}
+
+static void boundary_periodic_read (GtsObject ** object, GtsFile * fp)
+{
+  boundary_periodic_destroy (*object);
+}
+
+static void center_periodic (FttCellFace * face, GfsBc * b)
+{
+  GfsBoundaryPeriodic * boundary_periodic = GFS_BOUNDARY_PERIODIC (b->b);
+
+  g_assert (boundary_periodic->sndcount < boundary_periodic->sndbuf->len);
+  g_assert (ftt_face_type (face) == FTT_FINE_FINE);
+  g_assert (!FTT_CELL_IS_LEAF (face->cell) || FTT_CELL_IS_LEAF (face->neighbor));
+  g_array_index (boundary_periodic->sndbuf, gdouble, boundary_periodic->sndcount++) =
+    GFS_VARIABLE (face->neighbor, b->v->i);
+}
+
+static void face_periodic (FttCellFace * face, GfsBc * b)
+{
+  GfsBoundaryPeriodic * boundary_periodic = GFS_BOUNDARY_PERIODIC (b->b);
+
+  g_assert (boundary_periodic->sndcount < boundary_periodic->sndbuf->len);
+  g_array_index (boundary_periodic->sndbuf, gdouble, boundary_periodic->sndcount++) =
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v;
+}
+
+static void boundary_size (FttCell * cell, guint * count)
+{
+  (*count)++;
+}
+
+static void set_buffers_size (GfsBoundaryPeriodic * boundary)
+{
+  guint count = 0;
+
+  ftt_cell_traverse (GFS_BOUNDARY (boundary)->root, 
+		     FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) boundary_size, &count);
+  g_array_set_size (boundary->rcvbuf, count);
+  g_array_set_size (boundary->sndbuf, count);
+}
+
+static void boundary_tree (FttCell * cell, GfsBoundaryPeriodic * boundary)
+{
+  gdouble is_leaf = FTT_CELL_IS_LEAF (cell);
+
+  if (boundary->sndcount == boundary->sndbuf->len)
+    g_array_append_val (boundary->sndbuf, is_leaf);
+  else
+    g_array_index (boundary->sndbuf, gdouble, boundary->sndcount) = is_leaf;
+  boundary->sndcount++;
+
+  if (!is_leaf) {
+    FttCellChildren child;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, GFS_BOUNDARY (boundary)->d, &child);
+    for (i = 0; i < n; i++) {
+      /* fixme: using a gdouble to store (and MPI transfer) a boolean is wasteful... */
+      gdouble is_destroyed = (child.c[i] == NULL);
+      
+      if (boundary->sndcount == boundary->sndbuf->len)
+	g_array_append_val (boundary->sndbuf, is_destroyed);
+      else
+	g_array_index (boundary->sndbuf, gdouble, boundary->sndcount) = is_destroyed;
+      boundary->sndcount++;
+    }
+    for (i = 0; i < n; i++)
+      if (child.c[i])
+	boundary_tree (child.c[i], boundary);
+  }
+}
+
+static void periodic_match (GfsBoundary * boundary)
+{
+  (* gfs_boundary_class ()->match) (boundary);
+
+  g_assert (GFS_BOUNDARY_PERIODIC (boundary)->sndcount == 0);
+  boundary_tree (boundary->root, GFS_BOUNDARY_PERIODIC (boundary));
+}
+
+static void send (GfsBoundary * bb)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+  g_assert (boundary->matching);
+  GfsBoundaryPeriodic * matching = 
+    GFS_BOUNDARY_PERIODIC (boundary->matching->neighbor[boundary->d]);
+
+  g_assert (GFS_IS_BOUNDARY_PERIODIC (matching));
+  g_assert (boundary->sndcount <= boundary->sndbuf->len);
+  
+  if (GFS_BOUNDARY (boundary)->type == GFS_BOUNDARY_MATCH_VARIABLE) {
+    if (boundary->sndcount > matching->rcvbuf->len)
+      g_array_set_size (matching->rcvbuf, boundary->sndcount);
+  }
+  memcpy (matching->rcvbuf->data, boundary->sndbuf->data, boundary->sndcount*sizeof (gdouble));
+}
+
+static void center_update (FttCell * cell,
+			   GfsBoundaryPeriodic * boundary)
+{
+  g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+  GFS_VARIABLE (cell, GFS_BOUNDARY (boundary)->v->i) =
+    g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+}
+
+static void face_update (FttCellFace * face,
+			 GfsBoundaryPeriodic * boundary)
+{
+  g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+  GFS_STATE (face->cell)->f[face->d].v = 
+    g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+}
+
+static void match_ignore (GfsBoundaryPeriodic * boundary)
+{
+  gboolean is_leaf;
+
+  g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+  is_leaf = g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+
+  if (!is_leaf) {
+    gboolean is_destroyed[FTT_CELLS/2];
+    guint i;
+
+    for (i = 0; i < FTT_CELLS/2; i++) {
+      g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+      is_destroyed[i] = g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+    }
+    for (i = 0; i < FTT_CELLS/2; i++)
+      if (!is_destroyed[i])
+	match_ignore (boundary);
+  }
+}
+
+static void match_update (FttCell * cell,
+			  GfsBoundaryPeriodic * boundary)
+{
+  gboolean is_leaf;
+
+  g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+  is_leaf = g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+
+  if (!is_leaf) {
+    GfsDomain * domain = gfs_box_domain (GFS_BOUNDARY (boundary)->box);
+    FttCellChildren child;
+    gboolean is_destroyed[FTT_CELLS/2];
+    guint i, n;
+
+    if (FTT_CELL_IS_LEAF (cell)) {
+      FttCell * neighbor = ftt_cell_neighbor (cell, GFS_BOUNDARY (boundary)->d);
+
+      g_assert (neighbor);
+      ftt_cell_refine_single (cell, domain->cell_init, domain->cell_init_data);
+      if (FTT_CELL_IS_LEAF (neighbor))
+	ftt_cell_refine_single (neighbor, domain->cell_init, domain->cell_init_data);
+      /* what about solid fractions? */
+      GFS_BOUNDARY (boundary)->changed = TRUE;
+    }
+    n = ftt_cell_children_direction (cell, GFS_BOUNDARY (boundary)->d, &child);
+    for (i = 0; i < n; i++) {
+      g_assert (boundary->rcvcount < boundary->rcvbuf->len);
+      is_destroyed[i] = g_array_index (boundary->rcvbuf, gdouble, boundary->rcvcount++);
+      if (is_destroyed[i] && child.c[i]) {
+	ftt_cell_destroy (child.c[i], (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+	child.c[i] = NULL;
+	GFS_BOUNDARY (boundary)->changed = TRUE;
+      }
+    }
+    for (i = 0; i < n; i++)
+      if (!is_destroyed[i]) {
+	if (child.c[i])
+	  match_update (child.c[i], boundary);
+	else
+	  match_ignore (boundary);
+      }
+  }
+}
+
+static void receive (GfsBoundary * bb,
+		     FttTraverseFlags flags,
+		     gint max_depth)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+
+  boundary->rcvcount = 0;
+  switch (GFS_BOUNDARY (boundary)->type) {
+  case GFS_BOUNDARY_FACE_VARIABLE:
+    ftt_face_traverse_boundary (GFS_BOUNDARY (boundary)->root,
+				GFS_BOUNDARY (boundary)->d,
+				FTT_PRE_ORDER, flags, max_depth,
+				(FttFaceTraverseFunc) face_update, boundary);
+    break;
+
+  case GFS_BOUNDARY_MATCH_VARIABLE:
+    match_update (GFS_BOUNDARY (boundary)->root, boundary);
+    ftt_cell_flatten (GFS_BOUNDARY (boundary)->root, 
+		      GFS_BOUNDARY (boundary)->d,
+		      (FttCellCleanupFunc) gfs_cell_cleanup, 
+		      gfs_box_domain (GFS_BOUNDARY (boundary)->box));
+    break;
+
+  default:
+    ftt_cell_traverse (GFS_BOUNDARY (boundary)->root,
+		       FTT_PRE_ORDER, flags, max_depth,
+		       (FttCellTraverseFunc) center_update, boundary);
+  }
+}
+
+static void synchronize (GfsBoundary * bb)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+
+  boundary->sndcount = 0;
+  if (bb->type == GFS_BOUNDARY_MATCH_VARIABLE)
+    set_buffers_size (boundary);
+}
+
+static GtsColor periodic_color (GtsObject * o)
+{
+  GtsColor c = { 1., 0., 0. }; /* red */
+
+  return c;
+}
+
+static void gfs_boundary_periodic_class_init (GfsBoundaryClass * klass)
+{
+  GfsBoundaryClass * parent_class = GFS_BOUNDARY_CLASS (klass);
+
+  parent_class->match             = periodic_match;
+  parent_class->send              = send;
+  parent_class->receive           = receive;
+  parent_class->synchronize       = synchronize;
+
+  GTS_OBJECT_CLASS (klass)->color =   periodic_color;
+  GTS_OBJECT_CLASS (klass)->destroy = boundary_periodic_destroy;
+  GTS_OBJECT_CLASS (klass)->read    = boundary_periodic_read;
+}
+
+static void gfs_boundary_periodic_init (GfsBoundaryPeriodic * boundary)
+{
+  GfsBc * b = GFS_BOUNDARY (boundary)->default_bc;
+
+  b->bc                = (FttFaceTraverseFunc) center_periodic;
+  b->homogeneous_bc    = (FttFaceTraverseFunc) center_periodic;
+  b->face_bc           = (FttFaceTraverseFunc) face_periodic;
+
+  boundary->sndbuf = g_array_new (FALSE, FALSE, sizeof (gdouble));
+  boundary->rcvbuf = g_array_new (FALSE, FALSE, sizeof (gdouble));
+  boundary->sndcount = boundary->rcvcount = 0;
+
+  boundary->rotate = 0.;
+}
+
+GfsBoundaryClass * gfs_boundary_periodic_class (void)
+{
+  static GfsBoundaryClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_periodic_info = {
+      "GfsBoundaryPeriodic",
+      sizeof (GfsBoundaryPeriodic),
+      sizeof (GfsBoundaryClass),
+      (GtsObjectClassInitFunc) gfs_boundary_periodic_class_init,
+      (GtsObjectInitFunc) gfs_boundary_periodic_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_boundary_class ()),
+				  &gfs_boundary_periodic_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_boundary_periodic_new:
+ * @klass: a #GfsBoundaryClass.
+ * @box: a #GfsBox.
+ * @d: a #FttDirection.
+ * @matching: a #GfsBox.
+ *
+ * Returns: a new #GfsBoundaryPeriodic connecting @box with @matching in direction @d.
+ */
+GfsBoundaryPeriodic * gfs_boundary_periodic_new (GfsBoundaryClass * klass,
+						 GfsBox * box,
+						 FttDirection d,
+						 GfsBox * matching)
+{
+  GfsBoundaryPeriodic * boundary;
+
+  boundary = GFS_BOUNDARY_PERIODIC (gfs_boundary_new (klass, box, d));
+  set_buffers_size (boundary);
+  boundary->matching = matching;
+  boundary->d = FTT_OPPOSITE_DIRECTION (d);
+
+  return boundary;
+}
+
+static void center_periodic_rotate (FttCellFace * face, GfsBc * b)
+{
+  GfsBoundaryPeriodic * boundary_periodic = GFS_BOUNDARY_PERIODIC (b->b);
+
+  g_assert (boundary_periodic->sndcount < boundary_periodic->sndbuf->len);
+  g_assert (ftt_face_type (face) == FTT_FINE_FINE);
+  g_assert (!FTT_CELL_IS_LEAF (face->cell) || FTT_CELL_IS_LEAF (face->neighbor));
+
+  if (b->v->component < 2) { /* 2D-vector-rotation only */
+    FttComponent c = FTT_ORTHOGONAL_COMPONENT (b->v->component);
+    g_assert (b->v->vector[c]);
+    g_array_index (boundary_periodic->sndbuf, gdouble, boundary_periodic->sndcount++) =
+      (2.*c - 1.)*boundary_periodic->rotate*GFS_VALUE (face->neighbor, b->v->vector[c]);
+  }
+  else
+    g_array_index (boundary_periodic->sndbuf, gdouble, boundary_periodic->sndcount++) =
+      GFS_VALUE (face->neighbor, b->v);
+}
+
+/**
+ * gfs_boundary_periodic_rotate_new:
+ * @klass: a #GfsBoundaryClass.
+ * @box: a #GfsBox.
+ * @d: a #FttDirection.
+ * @matching: a #GfsBox.
+ * @rotate: a #FttDirection.
+ * @orientation: the orientation (+1 or -1).
+ *
+ * Returns: a new "rotated" #GfsBoundaryPeriodic connecting @box in
+ * direction @d with @matching in direction @rotate, oriented using
+ * @orientation.
+ */
+GfsBoundaryPeriodic * gfs_boundary_periodic_rotate_new (GfsBoundaryClass * klass,
+							GfsBox * box,
+							FttDirection d,
+							GfsBox * matching,
+							FttDirection rotate,
+							gdouble orientation)
+{
+  GfsBoundaryPeriodic * boundary;
+
+  boundary = gfs_boundary_periodic_new (klass, box, d, matching);
+  boundary->d = rotate;
+  boundary->rotate = orientation;
+
+  GfsBc * b = GFS_BOUNDARY (boundary)->default_bc;
+  b->bc = b->homogeneous_bc = (FttFaceTraverseFunc) center_periodic_rotate;
+
+  return boundary;
+}
+
+/* GfsGEdge: Object */
+
+static void gfs_gedge_write (GtsObject * object, FILE * fp)
+{
+  fprintf (fp, " %s", ftt_direction_name [GFS_GEDGE (object)->d]);
+  if (GFS_GEDGE (object)->rotate < FTT_NEIGHBORS)
+    fprintf (fp, " %s", ftt_direction_name [GFS_GEDGE (object)->rotate]);
+}
+
+static void gfs_gedge_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsGEdge * e = GFS_GEDGE (*o);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (direction)");
+    return;
+  }
+  e->d = ftt_direction_from_name (fp->token->str);
+  if (e->d >= FTT_NEIGHBORS) {
+    gts_file_error (fp, "unknown direction `%s'", fp->token->str);
+    e->d = 0;
+    return;
+  }
+  gts_file_next_token (fp);
+  if (fp->type == GTS_STRING) {
+    e->rotate = ftt_direction_from_name (fp->token->str);
+    if (e->rotate >= FTT_NEIGHBORS) {
+      gts_file_error (fp, "unknown direction `%s'", fp->token->str);
+      e->rotate = -1;
+      return;
+    }
+    gts_file_next_token (fp);
+  }
+}
+
+static void gfs_gedge_class_init (GtsObjectClass * klass)
+{
+  klass->write = gfs_gedge_write;
+  klass->read = gfs_gedge_read;
+}
+
+static void gfs_gedge_init (GfsGEdge * object)
+{
+  object->d = object->rotate = FTT_NEIGHBORS;
+}
+
+GfsGEdgeClass * gfs_gedge_class (void)
+{
+  static GfsGEdgeClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_gedge_info = {
+      "GfsGEdge",
+      sizeof (GfsGEdge),
+      sizeof (GfsGEdgeClass),
+      (GtsObjectClassInitFunc) gfs_gedge_class_init,
+      (GtsObjectInitFunc) gfs_gedge_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_gedge_class ()),
+				  &gfs_gedge_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_gedge_link_boxes:
+ * @edge: a #GfsGEdge.
+ *
+ * Links the two boxes connected by @edge. The boxes are set as their
+ * respective neighbors in the direction defined by @edge (note that
+ * their relative positions are not set).
+ */
+void gfs_gedge_link_boxes (GfsGEdge * edge)
+{
+  GfsBox * b1, * b2;
+
+  g_return_if_fail (edge != NULL);
+  g_return_if_fail (GTS_GEDGE (edge)->n1 != NULL);
+  g_return_if_fail (GTS_GEDGE (edge)->n2 != NULL);
+  g_return_if_fail (edge->d >= 0 && edge->d < FTT_NEIGHBORS);
+
+  b1 = GFS_BOX (GTS_GEDGE (edge)->n1);
+  b2 = GFS_BOX (GTS_GEDGE (edge)->n2);
+
+  g_return_if_fail (b1->neighbor[edge->d] == NULL);
+  
+  if (edge->rotate < FTT_NEIGHBORS) {
+    g_return_if_fail (b2->neighbor[edge->rotate] == NULL);
+    gfs_boundary_periodic_rotate_new (gfs_boundary_periodic_class (),
+				      b1, edge->d, b2, edge->rotate,  1.);
+    gfs_boundary_periodic_rotate_new (gfs_boundary_periodic_class (),
+				      b2, edge->rotate, b1, edge->d, -1.);
+  }
+  else {
+    g_return_if_fail (b2->neighbor[FTT_OPPOSITE_DIRECTION (edge->d)] == NULL);
+    
+    GtsObject * periodic = GTS_OBJECT (b1);
+    while (periodic && GFS_IS_BOX (periodic) && GFS_BOX (periodic) != b2)
+      periodic = GFS_BOX (periodic)->neighbor[FTT_OPPOSITE_DIRECTION (edge->d)];
+    
+    if (GFS_BOX (periodic) == b2) {
+      gfs_boundary_periodic_new (gfs_boundary_periodic_class (), b1, edge->d, b2);
+      gfs_boundary_periodic_new (gfs_boundary_periodic_class (), b2, 
+				 FTT_OPPOSITE_DIRECTION (edge->d), b1);
+    }
+    else {
+      ftt_cell_set_neighbor (b1->root, b2->root, edge->d, 
+			     (FttCellInitFunc) gfs_cell_init, gfs_box_domain (b1));
+      b1->neighbor[edge->d] = GTS_OBJECT (b2);
+      b2->neighbor[FTT_OPPOSITE_DIRECTION (edge->d)] = GTS_OBJECT (b1);
+    }
+  }
+}
+
+/**
+ * gfs_gedge_new:
+ * @klass: a #GfsGEdgeClass.
+ * @b1: a #GfsBox.
+ * @b2: another #GfsBox.
+ * @d: a direction.
+ *
+ * Returns: a new #GfsGEdge linking @b1 to @b2 in direction @d. The
+ * boxes are linked using gfs_gedge_link_boxes().
+ */
+GfsGEdge * gfs_gedge_new (GfsGEdgeClass * klass,
+			  GfsBox * b1, GfsBox * b2,
+			  FttDirection d)
+{
+  GfsGEdge * edge;
+
+  g_return_val_if_fail (klass != NULL, NULL);
+  g_return_val_if_fail (b1 != NULL, NULL);
+  g_return_val_if_fail (b2 != NULL, NULL);
+  g_return_val_if_fail (d >= 0 && d < FTT_NEIGHBORS, NULL);
+
+  edge = GFS_GEDGE (gts_gedge_new (GTS_GEDGE_CLASS (klass),
+				   GTS_GNODE (b1), GTS_GNODE (b2)));
+  edge->d = d;
+  
+  gfs_gedge_link_boxes (edge);
+
+  return edge;
+}
+
+/* GfsBox: Object */
+
+static void gfs_box_destroy (GtsObject * object)
+{
+  GfsBox * box = GFS_BOX (object);
+  FttDirection d;
+
+  if (box->root) {
+    GfsDomain * domain = gfs_box_domain (box);
+    if (domain == NULL) /* domain has been destroyed */
+      ftt_cell_destroy (box->root, NULL, NULL);
+    else
+      ftt_cell_destroy (box->root, (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+  }
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]))
+      gts_object_destroy (box->neighbor[d]);
+    else if (GFS_IS_BOX (box->neighbor[d])) {
+      g_assert (GFS_BOX (box->neighbor[d])->neighbor[FTT_OPPOSITE_DIRECTION (d)] == GTS_OBJECT (box));
+      GFS_BOX (box->neighbor[d])->neighbor[FTT_OPPOSITE_DIRECTION (d)] = NULL;
+    }
+
+  (* GTS_OBJECT_CLASS (gfs_box_class ())->parent_class->destroy) (object);
+}
+
+static void box_size (FttCell * cell, guint * size)
+{
+  (*size)++;
+}
+
+static void gfs_box_write (GtsObject * object, FILE * fp)
+{
+  GfsBox * box = GFS_BOX (object);
+  FttVector pos;
+  FttDirection d;
+  guint size = 0;
+  GfsDomain * domain = gfs_box_domain (box);
+
+  ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		     (FttCellTraverseFunc) box_size, &size);
+  ftt_cell_pos (box->root, &pos);
+  fprintf (fp, "%s { id = %u pid = %d size = %u x = %g y = %g z = %g",
+	   object->klass->info.name, box->id, box->pid, size, pos.x, pos.y, pos.z);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d])) {
+      fprintf (fp, " %s = %s",
+	       ftt_direction_name[d],
+	       box->neighbor[d]->klass->info.name);
+      if (box->neighbor[d]->klass->write)
+	(* box->neighbor[d]->klass->write) (box->neighbor[d], fp);
+    }
+  fputs (" }", fp);
+  if (domain != NULL && domain->max_depth_write > -2) {
+    fputs (" {\n", fp);
+    if (domain->binary)
+      ftt_cell_write_binary (box->root, domain->max_depth_write, fp, 
+			     (FttCellWriteFunc) gfs_cell_write_binary, domain->variables_io);
+    else
+      ftt_cell_write (box->root, domain->max_depth_write, fp, 
+		      (FttCellWriteFunc) gfs_cell_write, domain->variables_io);
+    fputc ('}', fp);
+  }
+}
+
+static void gfs_box_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBox * b = GFS_BOX (*o);
+  GtsObjectClass * klass;
+  gboolean class_changed = FALSE;
+  FttVector pos = {0., 0., 0.};
+  GtsFileVariable var[] = {
+    {GTS_UINT,   "id",     TRUE},
+    {GTS_INT,    "pid",    TRUE},
+    {GTS_UINT,   "size",   TRUE},
+    {GTS_DOUBLE, "x",      TRUE},
+    {GTS_DOUBLE, "y",      TRUE},
+    {GTS_DOUBLE, "z",      TRUE},
+    {GTS_FILE,   "right",  TRUE},
+    {GTS_FILE,   "left",   TRUE},
+    {GTS_FILE,   "top",    TRUE},
+    {GTS_FILE,   "bottom", TRUE},
+#if (!FTT_2D)
+    {GTS_FILE,   "front",  TRUE},
+    {GTS_FILE,   "back",   TRUE},
+#endif /* 3D */
+    {GTS_NONE}
+  };
+  GtsFileVariable * v;
+  gfloat weight;
+  GfsDomain * domain = GTS_OBJECT (*o)->reserved;
+
+  if (domain == NULL) {
+    g_assert (GTS_SLIST_CONTAINEE (b)->containers &&
+	      !GTS_SLIST_CONTAINEE (b)->containers->next);
+    domain = GFS_DOMAIN (GTS_SLIST_CONTAINEE (b)->containers->data);
+  }
+  else
+    gts_container_add (GTS_CONTAINER (domain), GTS_CONTAINEE (b));
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsBoxClass)");
+    return;
+  }
+  klass = gfs_object_class_from_name (fp->token->str);
+  if (klass == NULL) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_box_class ())) {
+    gts_file_error (fp, "`%s' is not a GfsBox", fp->token->str);
+    return;
+  }
+  if (klass != (*o)->klass) {
+    *o = gts_object_new (klass);
+    gts_object_destroy (GTS_OBJECT (b));
+    b = GFS_BOX (*o);
+    gts_container_add (GTS_CONTAINER (domain), GTS_CONTAINEE (b));
+    class_changed = TRUE;
+  }
+  gts_file_next_token (fp);
+
+  g_assert (b->root == NULL);
+  b->root = ftt_cell_new ((FttCellInitFunc) gfs_cell_init, domain);
+
+  weight = gts_gnode_weight (GTS_GNODE (b));
+  var[0].data = &b->id;
+  var[1].data = &b->pid;
+  var[2].data = &b->size;
+  var[3].data = &pos.x;
+  var[4].data = &pos.y;
+  var[5].data = &pos.z;
+  gts_file_assign_start (fp, var);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  while ((v = gts_file_assign_next (fp, var)))
+    if (v->type == GTS_FILE) {
+      GtsObjectClass * boundary_class = gfs_object_class_from_name (fp->token->str);
+      GtsObject * boundary;
+	
+      if (boundary_class == NULL) {
+	gts_file_error (fp, "unknown class `%s'", fp->token->str);
+	return;
+      }
+      if (!gts_object_class_is_from_class (boundary_class, gfs_boundary_class ())) {
+	gts_file_error (fp, "`%s' is not a GfsBoundary", fp->token->str);
+	return;
+      }
+      boundary = GTS_OBJECT (gfs_boundary_new (GFS_BOUNDARY_CLASS (boundary_class),
+					       b, ftt_direction_from_name (v->name)));
+      gts_file_next_token (fp);
+      if (boundary_class->read)
+	(* boundary_class->read) (&boundary, fp);
+    }
+  
+  if (fp->type == '{') {
+    FttDirection d;
+
+    ftt_cell_destroy (b->root, (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+    fp->scope_max++;
+    if (domain->binary) {
+      if (gts_file_getc (fp) != '\n') {
+      	gts_file_error (fp, "expecting a newline");
+      	return;
+      }
+      b->root = ftt_cell_read_binary (fp, (FttCellReadFunc) gfs_cell_read_binary, domain);
+      if (fp->type == GTS_ERROR)
+	return;
+      gts_file_next_token (fp);
+    }
+    else {
+      gts_file_first_token_after (fp, '\n');
+      b->root = ftt_cell_read (fp, (FttCellReadFunc) gfs_cell_read, domain);
+    }
+    fp->scope_max--;
+    if (fp->type == GTS_ERROR)
+      return;
+    if (fp->type != '}') {
+      gts_file_error (fp, "expecting a closing brace");
+      return;
+    }
+    gts_file_next_token (fp);
+
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY (b->neighbor[d])) {
+	GfsBoundary * boundary = GFS_BOUNDARY (b->neighbor[d]);
+
+	ftt_cell_set_neighbor_match (boundary->root, b->root, boundary->d, 
+				     (FttCellInitFunc) gfs_cell_init, domain);
+      }
+  }
+
+  FTT_ROOT_CELL (b->root)->parent = b;
+  if (ftt_cell_level (b->root) != domain->rootlevel) {
+    FttDirection d;
+
+    ftt_cell_set_level (b->root, domain->rootlevel);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY (b->neighbor[d]))
+	ftt_cell_set_level (GFS_BOUNDARY (b->neighbor[d])->root, domain->rootlevel);
+  }
+
+  if (var[3].set || var[4].set || var[5].set) {
+    gdouble size = ftt_cell_size (b->root);
+    FttDirection d;
+    ftt_cell_set_pos (b->root, &pos);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY (b->neighbor[d])) {
+	FttVector bpos = pos;
+	bpos.x += rpos[d].x*size;
+	bpos.y += rpos[d].y*size;
+	bpos.z += rpos[d].z*size;
+	ftt_cell_set_pos (GFS_BOUNDARY (b->neighbor[d])->root, &bpos);
+      }
+  }
+  else /* position is not set */
+    FTT_ROOT_CELL (b->root)->pos.x = G_MAXDOUBLE;
+
+  /* updates weight of domain */
+  GTS_WGRAPH (domain)->weight += gts_gnode_weight (GTS_GNODE (b)) - weight;
+
+  if (class_changed && klass->read)
+    (* klass->read) (o, fp);
+}
+
+static gfloat gfs_box_weight (GtsGNode * node)
+{
+  GfsBox * box = GFS_BOX (node);
+
+  if (box->size >= 0)
+    return box->size;
+  else {
+    guint size = 0;
+
+    if (box->root)
+      ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			 (FttCellTraverseFunc) box_size, &size);
+    return size;
+  }
+}
+
+static void gfs_box_class_init (GfsBoxClass * klass)
+{
+  GTS_GNODE_CLASS (klass)->weight = gfs_box_weight;
+
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_box_destroy;
+  GTS_OBJECT_CLASS (klass)->write = gfs_box_write;
+  GTS_OBJECT_CLASS (klass)->read = gfs_box_read;
+}
+
+static void gfs_box_init (GfsBox * box)
+{
+  static guint id = 1;
+
+  box->id = id++;
+  box->pid = -1;
+  box->size = -1;
+}
+
+GfsBoxClass * gfs_box_class (void)
+{
+  static GfsBoxClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_box_info = {
+      "GfsBox",
+      sizeof (GfsBox),
+      sizeof (GfsBoxClass),
+      (GtsObjectClassInitFunc) gfs_box_class_init,
+      (GtsObjectInitFunc) gfs_box_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_gnode_class ()),
+				  &gfs_box_info);
+  }
+
+  return klass;
+}
+
+GfsBox * gfs_box_new (GfsBoxClass * klass)
+{
+  GfsBox * object;
+
+  object = GFS_BOX (gts_object_new (GTS_OBJECT_CLASS (klass)));
+
+  return object;
+}
+
diff --git a/src/boundary.h b/src/boundary.h
new file mode 100644
index 0000000..217ca7f
--- /dev/null
+++ b/src/boundary.h
@@ -0,0 +1,353 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __BOUNDARY_H__
+#define __BOUNDARY_H__
+
+#include "fluid.h"
+#include "utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GfsBox                    GfsBox;
+typedef struct _GfsBoxClass               GfsBoxClass;
+typedef struct _GfsBoundary               GfsBoundary;
+typedef struct _GfsBoundaryClass          GfsBoundaryClass;
+
+/* GfsBc: Header */
+
+typedef struct _GfsBc         GfsBc;
+
+struct _GfsBc {
+  /*< private >*/
+  GtsObject parent;
+
+  /*< public >*/
+  GfsBoundary * b;
+  GfsVariable * v;
+  gboolean extra;
+  FttFaceTraverseFunc bc, homogeneous_bc;
+  FttFaceTraverseFunc face_bc;
+};
+
+typedef struct _GfsBcClass    GfsBcClass;
+
+struct _GfsBcClass {
+  /*< private >*/
+  GtsObjectClass parent_class;
+
+  /*< public >*/  
+};
+
+#define GFS_BC(obj)                    GTS_OBJECT_CAST (obj,\
+				                        GfsBc,\
+				                        gfs_bc_class ())
+#define GFS_BC_CLASS(klass)            GTS_OBJECT_CLASS_CAST (klass,\
+						        GfsBcClass,\
+						        gfs_bc_class())
+#define GFS_IS_BC(obj)                 (gts_object_is_from_class (obj,\
+					gfs_bc_class ()))
+
+GfsBcClass * gfs_bc_class  (void);
+GfsBc *      gfs_bc_new    (GfsBcClass * k, 
+			    GfsVariable * v, 
+			    gboolean extra);
+
+/* GfsBcValue: Header */
+
+typedef struct _GfsBcValue         GfsBcValue;
+
+struct _GfsBcValue {
+  /*< private >*/
+  GfsBc parent;
+
+  /*< public >*/
+  GfsFunction * val;
+};
+
+#define GFS_BC_VALUE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsBcValue,\
+					         gfs_bc_value_class ())
+#define GFS_IS_BC_VALUE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_value_class ()))
+
+GfsBcClass * gfs_bc_value_class  (void);
+
+/* GfsBcDirichlet: Header */
+
+#define GFS_IS_BC_DIRICHLET(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_dirichlet_class ()))
+
+GfsBcClass * gfs_bc_dirichlet_class  (void);
+
+/* GfsBcNeumann: Header */
+
+#define GFS_IS_BC_NEUMANN(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_neumann_class ()))
+
+GfsBcClass * gfs_bc_neumann_class  (void);
+
+/* GfsBcNavier: Header */
+
+typedef struct _GfsBcNavier         GfsBcNavier;
+
+struct _GfsBcNavier {
+  /*< private >*/
+  GfsBcValue parent;
+
+  /*< public >*/
+  GfsFunction * lambda;
+};
+
+#define GFS_BC_NAVIER(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsBcNavier,\
+					         gfs_bc_navier_class ())
+#define GFS_IS_BC_NAVIER(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_navier_class ()))
+
+GfsBcClass * gfs_bc_navier_class  (void);
+
+/* GfsBoundary: Header */
+
+typedef enum {
+  GFS_BOUNDARY_CENTER_VARIABLE,
+  GFS_BOUNDARY_FACE_VARIABLE,
+  GFS_BOUNDARY_MATCH_VARIABLE,
+  GFS_BOUNDARY_VARIABLE_NUMBER
+} GfsBoundaryVariableType;
+
+struct _GfsBoundary {
+  /*< private >*/
+  GtsObject parent;
+
+  FttCell * root;
+  GfsBox * box;
+  FttDirection d;
+  guint depth;
+  GfsBc * default_bc;
+  gboolean changed;
+
+  /*< public >*/
+  GfsVariable * v;
+  GfsBoundaryVariableType type;
+  GHashTable * bc;
+};
+
+struct _GfsBoundaryClass {
+  GtsObjectClass parent_class;
+
+  void (* match)             (GfsBoundary * boundary);
+  void (* send)              (GfsBoundary * boundary);
+  void (* receive)           (GfsBoundary * boundary,
+			      FttTraverseFlags flags,
+			      gint max_depth);
+  void (* synchronize)       (GfsBoundary * boundary);
+};
+
+#define GFS_BOUNDARY(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsBoundary,\
+					           gfs_boundary_class ())
+#define GFS_BOUNDARY_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsBoundaryClass,\
+						   gfs_boundary_class())
+#define GFS_IS_BOUNDARY(obj)         (gts_object_is_from_class (obj,\
+						   gfs_boundary_class ()))
+     
+GfsBoundaryClass * gfs_boundary_class                (void);
+GfsBoundary *      gfs_boundary_new                  (GfsBoundaryClass * klass,
+						      GfsBox * box,
+						      FttDirection d);
+void               gfs_boundary_send                 (GfsBoundary * boundary);
+void               gfs_boundary_receive              (GfsBoundary * boundary,
+						      FttTraverseFlags flags,
+						      gint max_depth);
+void               gfs_boundary_synchronize          (GfsBoundary * boundary);
+GfsBc *            gfs_boundary_lookup_bc            (GfsBoundary * b, 
+						      GfsVariable * v);
+void               gfs_boundary_set_default_bc       (GfsBoundary * b, 
+						      GfsBc * bc);
+void               gfs_variable_set_default_bc       (GfsVariable * v, 
+						      GfsBc * bc);
+void               gfs_boundary_add_bc               (GfsBoundary * b, 
+						      GfsBc * bc);
+
+/* GfsBoundaryInflowConstant: Header */
+
+typedef struct _GfsBoundaryInflowConstant         GfsBoundaryInflowConstant;
+typedef struct _GfsBoundaryInflowConstantClass    GfsBoundaryInflowConstantClass;
+
+struct _GfsBoundaryInflowConstant {
+  GfsBoundary parent;
+
+  GfsFunction * un;
+};
+
+struct _GfsBoundaryInflowConstantClass {
+  GfsBoundaryClass parent_class;
+};
+
+#define GFS_BOUNDARY_INFLOW_CONSTANT(obj)  GTS_OBJECT_CAST (obj,\
+					 GfsBoundaryInflowConstant,\
+					 gfs_boundary_inflow_constant_class ())
+#define GFS_BOUNDARY_INFLOW_CONSTANT_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass,\
+					 GfsBoundaryInflowConstantClass,\
+					 gfs_boundary_inflow_constant_class())
+#define GFS_IS_BOUNDARY_INFLOW_CONSTANT(obj) (gts_object_is_from_class (obj,\
+					 gfs_boundary_inflow_constant_class ()))
+     
+GfsBoundaryInflowConstantClass * gfs_boundary_inflow_constant_class  (void);
+
+/* GfsBoundaryOutflow: Header */
+
+typedef struct _GfsBoundaryOutflowClass    GfsBoundaryOutflowClass;
+
+struct _GfsBoundaryOutflowClass {
+  GfsBoundaryClass parent_class;
+};
+
+#define GFS_BOUNDARY_OUTFLOW_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsBoundaryOutflowClass,\
+						   gfs_boundary_outflow_class())
+#define GFS_IS_BOUNDARY_OUTFLOW(obj)         (gts_object_is_from_class (obj,\
+					    gfs_boundary_outflow_class ()))
+     
+GfsBoundaryOutflowClass * gfs_boundary_outflow_class    (void);
+
+/* GfsBoundaryGradient: Header */
+
+#define GFS_IS_BOUNDARY_GRADIENT(obj)         (gts_object_is_from_class (obj,\
+					    gfs_boundary_gradient_class ()))
+     
+GfsBoundaryClass * gfs_boundary_gradient_class    (void);
+
+/* GfsBoundaryPeriodic: Header */
+
+typedef struct _GfsBoundaryPeriodic         GfsBoundaryPeriodic;
+
+struct _GfsBoundaryPeriodic {
+  /*< private >*/
+  GfsBoundary parent;
+
+  GfsBox * matching;
+  FttDirection d;
+  GArray * sndbuf, * rcvbuf;
+  guint sndcount, rcvcount;
+
+  gdouble rotate;
+};
+
+#define GFS_BOUNDARY_PERIODIC(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsBoundaryPeriodic,\
+					           gfs_boundary_periodic_class ())
+#define GFS_IS_BOUNDARY_PERIODIC(obj)         (gts_object_is_from_class (obj,\
+						   gfs_boundary_periodic_class ()))
+     
+GfsBoundaryClass *    gfs_boundary_periodic_class    (void);
+GfsBoundaryPeriodic * gfs_boundary_periodic_new      (GfsBoundaryClass * klass,
+						      GfsBox * box,
+						      FttDirection d,
+						      GfsBox * matching);
+GfsBoundaryPeriodic * gfs_boundary_periodic_rotate_new (GfsBoundaryClass * klass,
+							GfsBox * box,
+							FttDirection d,
+							GfsBox * matching,
+							FttDirection rotate,
+							gdouble orientation);
+
+/* GfsGEdge: Header */
+  
+typedef struct _GfsGEdge         GfsGEdge;
+typedef struct _GfsGEdgeClass    GfsGEdgeClass;
+
+struct _GfsGEdge {
+  GtsGEdge parent;
+
+  FttDirection d, rotate;
+};
+
+struct _GfsGEdgeClass {
+  GtsGEdgeClass parent_class;
+};
+
+#define GFS_GEDGE(obj)            GTS_OBJECT_CAST (obj,\
+					          GfsGEdge,\
+					          gfs_gedge_class ())
+#define GFS_GEDGE_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						  GfsGEdgeClass,\
+						  gfs_gedge_class())
+#define GFS_IS_GEDGE(obj)         (gts_object_is_from_class (obj,\
+						  gfs_gedge_class ()))
+     
+GfsGEdgeClass * gfs_gedge_class          (void);
+GfsGEdge *      gfs_gedge_new            (GfsGEdgeClass * klass,
+					  GfsBox * b1, GfsBox * b2,
+					  FttDirection d);
+void            gfs_gedge_link_boxes     (GfsGEdge * edge);
+
+struct _GfsBox {
+  GtsGNode parent;
+
+  FttCell * root;
+  GtsObject * neighbor[FTT_NEIGHBORS];
+  guint id;
+  int pid;
+  gint size;
+};
+
+struct _GfsBoxClass {
+  GtsGNodeClass parent_class;
+};
+
+#define GFS_BOX(obj)            GTS_OBJECT_CAST (obj,\
+					        GfsBox,\
+					        gfs_box_class ())
+#define GFS_BOX_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						      GfsBoxClass,\
+						      gfs_box_class())
+#define GFS_IS_BOX(obj)         (gts_object_is_from_class (obj,\
+						          gfs_box_class ()))
+     
+GfsBoxClass *    gfs_box_class                (void);
+GfsBox *         gfs_box_new                  (GfsBoxClass * klass);
+
+static inline
+GfsDomain * gfs_box_domain (GfsBox * box)
+{
+  GfsDomain * d;
+
+  g_return_val_if_fail (box != NULL, NULL);
+  
+  d = GTS_OBJECT (box)->reserved;
+  if (GTS_SLIST_CONTAINEE (box)->containers) {
+    GSList * i = GTS_SLIST_CONTAINEE (box)->containers;
+
+    while (i->next)
+      i = i->next;
+    d = i->data;
+  }
+  return d;
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BOUNDARY_H__ */
diff --git a/src/cartesian.c b/src/cartesian.c
new file mode 100644
index 0000000..fcd2628
--- /dev/null
+++ b/src/cartesian.c
@@ -0,0 +1,246 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2007 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "cartesian.h"
+
+/* GfsCartesianGrid: Object */
+
+static void gfs_cartesian_grid_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsCartesianGrid * cgd = GFS_CARTESIAN_GRID (*o);
+  guint i, j, size = 1;
+
+  if (GTS_OBJECT_CLASS (gfs_cartesian_grid_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_cartesian_grid_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  while (fp->type == '\n') 
+    gts_file_next_token (fp);
+  if (fp->type != GTS_INT) {
+     gts_file_error (fp, "expecting an integer (N)");
+     return;
+  }
+  cgd->N = atoi (fp->token->str);
+  gts_file_next_token (fp);
+
+  cgd->name = g_malloc0 (cgd->N*sizeof (char *));
+  for (i = 0; i < cgd->N; i++) {
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a string (name[%d])", i);
+      return;
+    }
+    cgd->name[i] = g_strdup (fp->token->str);
+    gts_file_next_token (fp);
+  }
+
+  cgd->n = g_malloc (cgd->N*sizeof (guint));  
+  for (i = 0; i < cgd->N; i++) {
+    while (fp->type == '\n') 
+      gts_file_next_token (fp);
+    if (fp->type != GTS_INT) {
+      gts_file_error (fp, "expecting an integer (n[%d])", i);
+      return;
+    }
+    cgd->n[i] = atoi (fp->token->str);
+    gts_file_next_token (fp);
+    size *= cgd->n[i];
+  }
+
+  cgd->x = g_malloc0 (cgd->N*sizeof (gdouble *));
+  for (i = 0; i < cgd->N; i++) {
+    cgd->x[i] = g_malloc (cgd->n[i]*sizeof (gdouble));
+    for (j = 0; j < cgd->n[i]; j++) {
+      if (fp->type == '\n')
+	gts_file_next_token (fp);
+      if (fp->type != GTS_FLOAT && fp->type != GTS_INT) {
+        gts_file_error (fp, "expecting a number (x[%d][%d])", i, j);
+        return;
+      }
+      cgd->x[i][j] = atof (fp->token->str);
+      gts_file_next_token (fp);
+    }
+  }
+
+  cgd->v = g_malloc (size*sizeof (gdouble));  
+  for (i = 0; i < size; i++) {
+    if (fp->type == '\n')
+      gts_file_next_token (fp);
+    if (fp->type != GTS_FLOAT && fp->type != GTS_INT) {
+      gts_file_error (fp, "expecting a number");
+      return;
+    }
+    cgd->v[i] = atof (fp->token->str);
+    gts_file_next_token (fp);
+  }
+}
+
+static void gfs_cartesian_grid_write (GtsObject * o, FILE * fp)
+{
+  GfsCartesianGrid * cgd = GFS_CARTESIAN_GRID (o);
+  guint i, j, size = 1;
+
+  if (GTS_OBJECT_CLASS (gfs_cartesian_grid_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_cartesian_grid_class ())->parent_class->write) 
+      (o, fp);
+
+  for (i = 0; i < cgd->N; i++)
+    size *= cgd->n[i];
+
+  fprintf (fp, "%d ", cgd->N);
+  for (i = 0; i < cgd->N; i++)
+    fprintf (fp, "%s ", cgd->name[i]);
+  fputc ('\n', fp);
+  for (i = 0; i < cgd->N; i++)
+    fprintf (fp, "%d\n", cgd->n[i]);
+
+  for (i = 0; i < cgd->N; i++)
+    for (j = 0; j < cgd->n[i]; j++)
+      fprintf (fp, "%f\n", cgd->x[i][j]);
+
+  for (i = 0; i < size; i++)
+    fprintf (fp, "%f\n", cgd->v[i]);  
+}
+
+static void gfs_cartesian_grid_destroy (GtsObject * object)
+{
+  GfsCartesianGrid * cgd = GFS_CARTESIAN_GRID (object);  
+
+  guint i;
+  if (cgd->name) {
+    for (i = 0; i < cgd->N; i++)
+      g_free (cgd->name[i]);
+    g_free (cgd->name);
+  }
+  g_free (cgd->n);
+  if (cgd->x) {
+    for (i = 0; i < cgd->N; i++)
+      g_free (cgd->x[i]);
+    g_free (cgd->x);
+  }
+  g_free (cgd->v);
+ 
+  (* GTS_OBJECT_CLASS (gfs_cartesian_grid_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_cartesian_grid_class_init (GtsObjectClass * klass)
+{
+  /* define new methods and overload inherited methods here */
+  GTS_OBJECT_CLASS (klass)->read = gfs_cartesian_grid_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_cartesian_grid_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_cartesian_grid_destroy;
+}
+
+GtsObjectClass * gfs_cartesian_grid_class (void)
+{
+  static GtsObjectClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_cartesian_grid_info = {
+      "GfsCartesianGrid",
+      sizeof (GfsCartesianGrid),
+      sizeof (GtsObjectClass),
+      (GtsObjectClassInitFunc) gfs_cartesian_grid_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+ 			  &gfs_cartesian_grid_info);
+  }
+
+  return klass;
+}
+
+GfsCartesianGrid * gfs_cartesian_grid_new (GtsObjectClass * klass)
+{
+  GfsCartesianGrid * object;
+
+  object = GFS_CARTESIAN_GRID (gts_object_new (GTS_OBJECT_CLASS (klass)));
+
+  return object;
+}
+
+static void slice (GfsCartesianGrid * g, guint p, GfsCartesianGrid * s)
+{
+  s->N = g->N - 1;
+  s->n = &g->n[1];
+  s->x = &g->x[1];
+  guint i;
+  gulong size = 1;
+  for (i = 1; i < g->N; i++)
+    size *= g->n[i];
+  s->v = &g->v[size*p];
+}
+
+static gint lookup (GfsCartesianGrid * g, gdouble x)
+{
+  guint min = 0, max = g->n[0] - 1;
+  if (x < g->x[0][min] || x > g->x[0][max])
+    return -1;
+  while (max > min + 1) {
+    guint n = (min + max)/2;
+    if (x > g->x[0][n])
+      min = n;
+    else
+      max = n;
+  }
+  return min;
+}
+
+/**
+ * gfs_cartesian_grid_interpolate:
+ * @g: a Cartesian grid.
+ * @p: a position vector of dimension @g->N.
+ * @val: the interpolated value at position @p.
+ *
+ * Returns: %TRUE if @val has been computed, %FALSE if @p is not
+ * contained within @g.
+ */
+gboolean gfs_cartesian_grid_interpolate (GfsCartesianGrid * g, gdouble * p, gdouble * val)
+{
+  g_return_val_if_fail (g != NULL, FALSE);
+  g_return_val_if_fail (g->N > 0, FALSE);
+  g_return_val_if_fail (p != NULL, FALSE);
+  g_return_val_if_fail (val != NULL, FALSE);
+
+  gint i = lookup (g, p[0]);
+  if (i < 0)
+    return FALSE;
+  gdouble v1, v2;
+  if (g->N > 1) {
+    GfsCartesianGrid g1;
+    slice (g, i, &g1);
+    if (!gfs_cartesian_grid_interpolate (&g1, &p[1], &v1))
+      return FALSE;
+    slice (g, i + 1, &g1);
+    if (!gfs_cartesian_grid_interpolate (&g1, &p[1], &v2))
+      return FALSE;
+  }
+  else {
+    v1 = g->v[i];
+    v2 = g->v[i + 1];
+  }
+
+  g_assert (g->x[0][i + 1] -  g->x[0][i] != 0.);
+  *val = v1 + (v2 - v1)*(p[0] - g->x[0][i])/(g->x[0][i + 1] -  g->x[0][i]);
+  return TRUE;
+}
diff --git a/src/cartesian.h b/src/cartesian.h
new file mode 100644
index 0000000..0a07bf0
--- /dev/null
+++ b/src/cartesian.h
@@ -0,0 +1,63 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2007 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __CARTESIAN_H__
+#define __CARTESIAN_H__
+
+#include <gts.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* GfsCartesianGrid: Header */
+
+typedef struct _GfsCartesianGrid      GfsCartesianGrid;
+
+struct _GfsCartesianGrid {
+  /*< private >*/
+  GtsObject parent;
+  guint N;       /* Number of dimensions */
+  guint * n;     /* Size of each dimension */
+  gdouble ** x;  /* Position of each point in the grid */
+  gdouble * v;   /* Data */
+  gchar ** name; /* Name of each dimension */
+
+
+  /*< public >*/
+  /* add extra data here (if public) */
+};
+
+#define GFS_CARTESIAN_GRID(obj)            GTS_OBJECT_CAST (obj,\
+							    GfsCartesianGrid, \
+							    gfs_cartesian_grid_class ())
+#define GFS_IS_CARTESIAN_GRID(obj)         (gts_object_is_from_class (obj,\
+								      gfs_cartesian_grid_class ()))
+
+GtsObjectClass *    gfs_cartesian_grid_class         (void);
+GfsCartesianGrid *  gfs_cartesian_grid_new           (GtsObjectClass * klass);
+gboolean            gfs_cartesian_grid_interpolate   (GfsCartesianGrid * g, 
+						      gdouble * p, 
+						      gdouble * val);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CARTESIAN_H__ */
diff --git a/src/domain.c b/src/domain.c
new file mode 100644
index 0000000..186faa6
--- /dev/null
+++ b/src/domain.c
@@ -0,0 +1,4343 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "domain.h"
+
+#include "advection.h"
+#include "source.h"
+#include "solid.h"
+#include "adaptive.h"
+#include "mpi_boundary.h"
+#include "metric.h"
+#include "version.h"
+
+#include "config.h"
+
+/* LocateArray */
+
+typedef struct {
+  GtsObject ** root;
+  gdouble h, min[FTT_DIMENSION], max[FTT_DIMENSION];
+  gint n[FTT_DIMENSION];
+} LocateArray;
+
+static void locate_index (FttVector * p, LocateArray * a, gint i[FTT_DIMENSION])
+{
+  gint c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    i[c] = floor (((&p->x)[c] - a->min[c])/a->h);
+}
+
+static void root_bounds (FttCell * root, LocateArray * a)
+{
+  FttVector p;
+  ftt_cell_pos (root, &p);
+  gint i;
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    if ((&p.x)[i] + a->h/2. > a->max[i]) a->max[i] = (&p.x)[i] + a->h/2.;
+    if ((&p.x)[i] - a->h/2. < a->min[i]) a->min[i] = (&p.x)[i] - a->h/2.;
+  }
+}
+
+static void box_bounds (GfsBox * box, LocateArray * a)
+{
+  root_bounds (box->root, a);
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]))
+      root_bounds (GFS_BOUNDARY (box->neighbor[d])->root, a);
+}
+
+static gint locate_linear_index (FttVector * p, LocateArray * a)
+{
+  gint i[FTT_DIMENSION], index = 0, c;
+  locate_index (p, a, i);
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    if (i[c] < 0 || i[c] >= a->n[c])
+      return -1;
+    index = index*a->n[c] + i[c];
+  }
+  return index;
+}
+
+static void box_index (GfsBox * b, LocateArray * a)
+{
+  FttVector p;
+  ftt_cell_pos (b->root, &p);
+  gint i = locate_linear_index (&p, a);
+  g_assert (i >= 0);
+  a->root[i] = GTS_OBJECT (b);
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (b->neighbor[d])) {
+      GfsBoundary * boundary = GFS_BOUNDARY (b->neighbor[d]);
+      ftt_cell_pos (boundary->root, &p);
+      gint i = locate_linear_index (&p, a);
+      g_assert (i >= 0);
+      a->root[i] = GTS_OBJECT (boundary);
+    }
+}
+
+/*
+ * Creates a rectangular array for fast location of which GfsBox
+ * contains a given point.
+ */
+static LocateArray * locate_array_new (GfsDomain * domain)
+{
+  LocateArray * a = g_malloc (sizeof (LocateArray));
+  guint i;
+  a->h = ftt_level_size (domain->rootlevel);
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    a->min[i] = G_MAXDOUBLE;
+    a->max[i] = - G_MAXDOUBLE;
+  }
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_bounds, a);
+  guint size = 1;
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    g_assert (a->max[i] > a->min[i]);
+    a->n[i] = ceil ((a->max[i] - a->min[i])/a->h - 0.5);
+    size *= a->n[i];
+  }
+  a->root = g_malloc0 (size*sizeof (GtsObject *));
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_index, a);
+  return a;
+}
+
+static GtsObject * locate_array_locate (LocateArray * a, FttVector * p)
+{
+  gint i = locate_linear_index (p, a);
+  return i < 0 ? NULL : a->root[i];
+}
+
+static void locate_array_destroy (LocateArray * a)
+{
+  if (a) {
+    g_free (a->root);
+    g_free (a);
+  }
+}
+
+/* GfsDomain: Object */
+
+static void domain_write (GtsObject * o, FILE * fp)
+{
+  GfsDomain * domain = GFS_DOMAIN (o);
+
+  if (GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class->write) (o, fp);
+
+  fputs (" { ", fp);
+  if (domain->rootlevel != 0)
+    fprintf (fp, "rootlevel = %u ", domain->rootlevel);
+  if (domain->refpos.x != 0.)
+    fprintf (fp, "x = %g ", domain->refpos.x);
+  if (domain->refpos.y != 0.)
+    fprintf (fp, "y = %g ", domain->refpos.y);
+  if (domain->refpos.z != 0.)
+    fprintf (fp, "z = %g ", domain->refpos.z);
+  if (domain->lambda.x != 1.)
+    fprintf (fp, "lx = %g ", domain->lambda.x);
+  if (domain->lambda.y != 1.)
+    fprintf (fp, "ly = %g ", domain->lambda.y);
+  if (domain->lambda.z != 1.)
+    fprintf (fp, "lz = %g ", domain->lambda.z);
+  fprintf (fp, "version = %d ", atoi (GFS_BUILD_VERSION));
+  if (!domain->overlap)
+    fputs ("overlap = 0 ", fp);
+  if (domain->max_depth_write > -2) {
+    GSList * i = domain->variables_io;
+
+    if (i != NULL) {
+      fprintf (fp, "variables = %s", GFS_VARIABLE1 (i->data)->name);
+      i = i->next;
+      while (i) {
+	fprintf (fp, ",%s", GFS_VARIABLE1 (i->data)->name);
+	i = i->next;
+      }
+      fputc (' ', fp);
+    }
+  }
+  if (domain->binary != FALSE)
+    fprintf (fp, "binary = 1 ");
+  fputc ('}', fp);
+}
+
+static void domain_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain = GFS_DOMAIN (*o);
+  GtsFileVariable var[] = {
+    {GTS_UINT,   "rootlevel", TRUE},
+    {GTS_DOUBLE, "x",         TRUE},
+    {GTS_DOUBLE, "y",         TRUE},
+    {GTS_DOUBLE, "z",         TRUE},
+    {GTS_DOUBLE, "lx",        TRUE},
+    {GTS_DOUBLE, "ly",        TRUE},
+    {GTS_DOUBLE, "lz",        TRUE},
+    {GTS_STRING, "variables", TRUE},
+    {GTS_INT,    "binary",    TRUE},
+    {GTS_INT,    "version",   TRUE},
+    {GTS_INT,    "overlap",   TRUE},
+    {GTS_NONE}
+  };
+  gchar * variables = NULL;
+
+  if (GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  domain->version = -1;
+  var[0].data = &domain->rootlevel;
+  var[1].data = &domain->refpos.x;
+  var[2].data = &domain->refpos.y;
+  var[3].data = &domain->refpos.z;
+  var[4].data = &domain->lambda.x;
+  var[5].data = &domain->lambda.y;
+  var[6].data = &domain->lambda.z;
+  var[7].data = &variables;
+  var[8].data = &domain->binary;
+  var[9].data = &domain->version;
+  var[10].data = &domain->overlap;
+  gts_file_assign_variables (fp, var);
+  if (fp->type == GTS_ERROR) {
+    g_free (variables);
+    return;
+  }
+
+#if FTT_2D
+  if (var[3].set) {
+    gts_file_variable_error (fp, var, "z", "unknown identifier `z'");
+    return;
+  }
+  if (var[6].set) {
+    gts_file_variable_error (fp, var, "lz", "unknown identifier `lz'");
+    return;
+  }
+#endif
+
+  if (var[4].set && domain->lambda.x <= 0.) {
+    gts_file_variable_error (fp, var, "lx", "lx must be strictly positive");
+    return;
+  }
+  if (var[5].set && domain->lambda.y <= 0.) {
+    gts_file_variable_error (fp, var, "ly", "ly must be strictly positive");
+    return;
+  }
+  if (var[6].set && domain->lambda.z <= 0.) {
+    gts_file_variable_error (fp, var, "lz", "lz must be strictly positive");
+    return;
+  }
+
+  if (variables != NULL) {
+    gchar * variables1, * s;
+
+    variables1 = g_strdup (variables);
+    s = strtok (variables1, ",");
+    while (s) {
+      gfs_domain_add_variable (domain, s, NULL);
+      s = strtok (NULL, ",");
+    }
+    g_free (variables1);
+    domain->variables_io = gfs_variables_from_list (domain->variables, variables, &s);
+    g_free (variables);
+  }
+}
+
+static void box_set_pos (GfsBox * box, FttVector * pos, 
+			 FttDirection dold)
+{
+  FttVector p;
+  static FttVector rpos[FTT_NEIGHBORS] = {
+#if FTT_2D
+    {1.,0.,0.}, {-1.,0.,0.}, {0.,1.,0.}, {0.,-1.,0.}
+#else  /* FTT_3D */
+    {1.,0.,0.}, {-1.,0.,0.}, {0.,1.,0.}, {0.,-1.,0.}, {0.,0.,1.}, {0.,0.,-1.}
+#endif /* FTT_3D */
+  };  
+  static FttDirection id[FTT_NEIGHBORS][FTT_NEIGHBORS] = {
+#if FTT_2D
+    {0,1,2,3},
+    {1,0,3,2},
+    {2,3,1,0},
+    {3,2,0,1},
+#else  /* 3D */
+    {0,1,2,3,5,4},
+    {1,0,3,2,4,5},
+    {2,3,1,0,5,4},
+    {3,2,0,1,4,5},
+    {4,5,2,3,0,1},
+    {5,4,3,2,1,0}
+#endif /* 3D */
+  };
+
+  ftt_cell_pos (box->root, &p);
+  if (p.x != G_MAXDOUBLE) /* position already set */
+    return;
+
+  FttDirection i;
+  gdouble size;
+  size = ftt_cell_size (box->root);
+  ftt_cell_set_pos (box->root, pos);
+  for (i = 0; i < FTT_NEIGHBORS; i++) {
+    FttDirection d = id[dold][i];
+    
+    p.x = pos->x + rpos[d].x*size;
+    p.y = pos->y + rpos[d].y*size;
+    p.z = pos->z + rpos[d].z*size;
+    if (GFS_IS_BOX (box->neighbor[d]))
+      box_set_pos (GFS_BOX (box->neighbor[d]), &p, d);
+    else if (GFS_IS_BOUNDARY (box->neighbor[d]))
+      ftt_cell_set_pos (GFS_BOUNDARY (box->neighbor[d])->root, &p);
+  }
+}
+
+static void set_ref_pos (GfsBox * box, FttVector * pos)
+{
+  if (box->id == 1)
+    box_set_pos (box, pos, FTT_RIGHT);
+}
+
+static void removed_list (GfsBox * box, gpointer * data)
+{
+  GfsDomain * domain = data[0];
+  GSList ** removed = data[1];
+  guint * np = data[2];
+  if (box->pid != domain->pid)
+    *removed = g_slist_prepend (*removed, box);
+  else {
+    FttDirection d;
+    GfsBox * matching;
+
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY_PERIODIC (box->neighbor[d]) &&
+	  (matching = GFS_BOUNDARY_PERIODIC (box->neighbor[d])->matching)->pid != domain->pid) {
+	gts_object_destroy (GTS_OBJECT (box->neighbor[d]));
+	gfs_boundary_mpi_new (gfs_boundary_mpi_class (), box, d, matching->pid, matching->id);
+      }
+  }
+  if (box->pid > *np)
+    *np = box->pid;
+}
+
+static void mpi_links (GfsBox * box, GfsDomain * domain)
+{
+  FttDirection d;
+  GtsObject * neighbor[FTT_NEIGHBORS];
+  gint pid = box->pid;
+  gint id = box->id;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOX (box->neighbor[d]) && GFS_BOX (box->neighbor[d])->pid == domain->pid)
+      neighbor[d] = box->neighbor[d];
+    else
+      neighbor[d] = NULL;
+  gts_object_destroy (GTS_OBJECT (box));
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (neighbor[d])
+      gfs_boundary_mpi_new (gfs_boundary_mpi_class (),
+			    GFS_BOX (neighbor[d]), 
+			    FTT_OPPOSITE_DIRECTION (d), 
+			    pid, id);
+}
+
+static void add_id (GfsBox * box, GPtrArray * ids)
+{
+  if (box->id > ids->len)
+    g_ptr_array_set_size (ids, box->id);
+  g_ptr_array_index (ids, box->id - 1) = box;
+}
+
+static GPtrArray * box_ids (GfsDomain * domain)
+{
+  GPtrArray * ids = g_ptr_array_new ();
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) add_id, ids);
+  return ids;
+}
+
+
+static void convert_boundary_mpi_into_edges (GfsBox * box, GPtrArray * ids)
+{
+  gint pid = gfs_box_domain (box)->pid;
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundaryMpi * b = GFS_BOUNDARY_MPI (box->neighbor[d]);
+      GfsBox * nbox;
+      if (b->id >= 0 && b->id <= ids->len && (nbox = g_ptr_array_index (ids, b->id - 1))) {
+	FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	if (!GFS_IS_BOUNDARY_MPI (nbox->neighbor[od]))
+	  g_warning ("!GFS_IS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)])");
+	else {
+	  GfsBoundaryMpi * nb = GFS_BOUNDARY_MPI (nbox->neighbor[od]);
+	  if (box->id != nb->id)
+	    g_warning ("box->id != nb->id");
+	  else {
+	    gts_object_destroy (GTS_OBJECT (b));
+	    gts_object_destroy (GTS_OBJECT (nb));
+	    gfs_gedge_new (gfs_gedge_class (), nbox, box, od);
+	  }
+	}
+      }
+    }
+  if (pid >= 0)
+    box->pid = pid;
+}
+
+static void domain_post_read (GfsDomain * domain, GtsFile * fp)
+{
+  gts_graph_foreach_edge (GTS_GRAPH (domain), (GtsFunc) gfs_gedge_link_boxes, NULL);
+
+  if (domain->pid >= 0) { /* Multiple PEs */
+    GSList * removed = NULL;
+    guint np = 0;
+    gpointer data[3];
+    
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) set_ref_pos, &domain->refpos);
+    data[0] = domain;
+    data[1] = &removed;
+    data[2] = &np;
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) removed_list, data);
+#ifdef HAVE_MPI
+    int comm_size;
+    MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
+    if (np + 1 != comm_size) {
+      g_slist_free (removed);
+      gts_file_error (fp, "it would be valid if one or %d PE were used", np + 1);
+      return;
+    }
+#endif /* HAVE_MPI */
+    g_slist_foreach (removed, (GFunc) mpi_links, domain);
+    g_slist_free (removed);
+  }
+  else { /* Single PE */
+    /* Create array for fast linking of ids to GfsBox pointers */
+    GPtrArray * ids = box_ids (domain);
+    
+    /* Convert GfsBoundaryMpi into graph edges */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) convert_boundary_mpi_into_edges, ids);
+
+    g_ptr_array_free (ids, TRUE);
+
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) set_ref_pos, &domain->refpos);
+  }
+
+  gfs_domain_match (domain);
+
+  locate_array_destroy (domain->array);
+  domain->array = locate_array_new (domain);
+
+  domain->version = atoi (GFS_BUILD_VERSION);
+}
+
+static void free_pair (gpointer key, gpointer value)
+{
+  g_free (key);
+  g_free (value);
+}
+
+static void cleanup_each_box (GfsBox * box, GfsDomain * domain)
+{
+  if (GFS_IS_BOX (box)) { /* this is a necessary check when using graph partitioning */
+    ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		       (FttCellTraverseFunc) gfs_cell_cleanup, domain);
+    FttDirection d;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY (box->neighbor[d]))
+	ftt_cell_traverse (GFS_BOUNDARY (box->neighbor[d])->root, 
+			   FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			   (FttCellTraverseFunc) gfs_cell_cleanup, domain);
+  }
+}
+
+static void domain_destroy (GtsObject * o)
+{
+  GfsDomain * domain = GFS_DOMAIN (o);
+  GSList * i;
+
+  gfs_clock_destroy (domain->timer);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) cleanup_each_box, domain);
+
+  i = domain->variables;
+  while (i) {
+    GSList * next = i->next;
+    gts_object_destroy (i->data);
+    i = next;
+  }
+  g_assert (domain->variables == NULL);
+
+  g_slist_foreach (domain->derived_variables, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (domain->derived_variables);
+  domain->derived_variables = NULL;
+
+  g_array_free (domain->allocated, TRUE);
+
+  g_hash_table_foreach (domain->timers, (GHFunc) free_pair, NULL);
+  g_hash_table_destroy (domain->timers);
+
+  g_slist_free (domain->variables_io);
+
+  locate_array_destroy (domain->array);
+
+  (* GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class->destroy) (o);
+}
+
+static void add_item (gpointer item, GPtrArray * a)
+{
+  g_ptr_array_add (a, item);
+}
+
+static int compare_boxes (const void * p1, const void * p2)
+{
+  GfsBox * b1 = *(GfsBox **)p1;
+  GfsBox * b2 = *(GfsBox **)p2;
+  /* the check below is necessary when using graph partitioning */  
+  if (GFS_IS_BOX (b1) && GFS_IS_BOX (b2))
+    return b1->id < b2->id ? -1 : 1;
+  else
+    return 0;
+}
+
+static void domain_foreach (GtsContainer * c, 
+			    GtsFunc func, 
+			    gpointer data)
+{
+  GPtrArray * a = g_ptr_array_new ();
+  (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gfs_domain_class ())->parent_class)->foreach)
+    (c, (GtsFunc) add_item, a);
+  qsort (a->pdata, a->len, sizeof (gpointer), compare_boxes);
+  guint i;
+  for (i = 0; i < a->len; i++)
+    (* func) (a->pdata[i], data);
+  g_ptr_array_free (a, TRUE);
+}
+
+static void domain_class_init (GfsDomainClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = domain_read;
+  GTS_OBJECT_CLASS (klass)->write = domain_write;
+  GTS_OBJECT_CLASS (klass)->destroy = domain_destroy;
+
+  GTS_CONTAINER_CLASS (klass)->foreach = domain_foreach;
+
+  klass->post_read = domain_post_read;
+}
+
+static void domain_init (GfsDomain * domain)
+{
+  domain->pid = -1;
+
+#ifdef HAVE_MPI
+  int size;
+
+  MPI_Comm_size (MPI_COMM_WORLD, &size);
+  if (size > 1)
+    MPI_Comm_rank (MPI_COMM_WORLD, &domain->pid);
+#endif /* HAVE_MPI */
+
+  domain->timer = gfs_clock_new ();
+  domain->timers = g_hash_table_new (g_str_hash, g_str_equal);
+
+  gts_range_init (&domain->size);
+
+  domain->profile_bc = FALSE;
+
+  gts_range_init (&domain->mpi_messages);
+  gts_range_init (&domain->mpi_wait);
+
+  domain->rootlevel = 0;
+  domain->refpos.x = domain->refpos.y = domain->refpos.z = 0.;
+  domain->lambda.x = domain->lambda.y = domain->lambda.z = 1.;
+
+  domain->allocated = g_array_new (FALSE, TRUE, sizeof (gboolean));
+  domain->variables = NULL;
+
+  domain->variables_io = NULL;
+  domain->max_depth_write = -1;
+
+  domain->cell_init = (FttCellInitFunc) gfs_cell_fine_init;
+  domain->cell_init_data = domain;
+
+  domain->version = atoi (GFS_BUILD_VERSION);
+
+  domain->overlap = TRUE;
+}
+
+GfsDomainClass * gfs_domain_class (void)
+{
+  static GfsDomainClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_domain_info = {
+      "GfsDomain",
+      sizeof (GfsDomain),
+      sizeof (GfsDomainClass),
+      (GtsObjectClassInitFunc) domain_class_init,
+      (GtsObjectInitFunc) domain_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_wgraph_class ()),
+				  &gfs_domain_info);
+  }
+
+  return klass;
+}
+
+typedef struct {
+  FttTraverseFlags flags;
+  gint max_depth;
+  GfsVariable * v, * v1;
+  FttComponent c;
+} BcData;
+
+static void box_bc (GfsBox * box, BcData * p)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) 
+    if (GFS_IS_BOUNDARY (box->neighbor[d])) {
+      GfsBoundary * b = GFS_BOUNDARY (box->neighbor[d]);
+      GfsBc * bc = gfs_boundary_lookup_bc (b, p->v);
+
+      if (bc) {
+	b->v = p->v1;
+	bc->v = p->v1;
+	b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+	ftt_face_traverse_boundary (b->root, b->d,
+				    FTT_PRE_ORDER, p->flags, p->max_depth,
+				    bc->bc, bc);
+	bc->v = p->v;
+	gfs_boundary_send (b);
+      }
+    }
+}
+
+static void direction_face_bc (GtsObject * neighbor,
+			       GfsVariable * v)
+{
+  if (GFS_IS_BOUNDARY (neighbor)) {
+    GfsBoundary * b = GFS_BOUNDARY (neighbor);
+    GfsBc * bc = gfs_boundary_lookup_bc (b, v);
+
+    if (bc) {
+      b->v = v;
+      b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+      ftt_face_traverse_boundary (b->root, b->d,
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  bc->face_bc, bc);
+      b->type = GFS_BOUNDARY_FACE_VARIABLE;
+      gfs_boundary_send (b);
+    }
+  }
+}
+
+static void box_face_bc (GfsBox * box, BcData * p)
+{
+  if (p->c == FTT_XYZ) {
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      direction_face_bc (box->neighbor[d], p->v);
+  }
+  else {
+    direction_face_bc (box->neighbor[2*p->c], p->v);
+    direction_face_bc (box->neighbor[2*p->c + 1], p->v);
+  }
+}
+
+static void box_receive_bc (GfsBox * box, BcData * r)
+{
+  if (r->c == FTT_XYZ) {
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++) {
+      FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+
+      if (GFS_IS_BOUNDARY (box->neighbor[od]))
+	gfs_boundary_receive (GFS_BOUNDARY (box->neighbor[od]), r->flags, r->max_depth);
+    }
+  }
+  else {
+    if (GFS_IS_BOUNDARY (box->neighbor[2*r->c + 1]))
+      gfs_boundary_receive (GFS_BOUNDARY (box->neighbor[2*r->c + 1]), r->flags, r->max_depth);
+    if (GFS_IS_BOUNDARY (box->neighbor[2*r->c]))
+      gfs_boundary_receive (GFS_BOUNDARY (box->neighbor[2*r->c]), r->flags, r->max_depth);
+  }
+}
+
+static void box_match (GfsBox * box)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d])) {
+      GfsBoundary * boundary = GFS_BOUNDARY (box->neighbor[d]);
+
+      g_assert (GFS_BOUNDARY_CLASS (box->neighbor[d]->klass)->match);
+      boundary->type = GFS_BOUNDARY_MATCH_VARIABLE;
+      (* GFS_BOUNDARY_CLASS (box->neighbor[d]->klass)->match) (boundary);
+      gfs_boundary_send (boundary);
+    }
+}
+
+static void box_synchronize (GfsBox * box, FttComponent * c)
+{
+  if (*c == FTT_XYZ) {
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_IS_BOUNDARY (box->neighbor[d]))
+	gfs_boundary_synchronize (GFS_BOUNDARY (box->neighbor[d]));
+  }
+  else {
+    if (GFS_IS_BOUNDARY (box->neighbor[2*(*c)]))
+      gfs_boundary_synchronize (GFS_BOUNDARY (box->neighbor[2*(*c)]));
+    if (GFS_IS_BOUNDARY (box->neighbor[2*(*c) + 1]))
+      gfs_boundary_synchronize (GFS_BOUNDARY (box->neighbor[2*(*c) + 1]));
+  }
+}
+
+/**
+ * gfs_domain_copy_bc:
+ * @domain: a #GfsDomain.
+ * @flags: the traversal flags.
+ * @max_depth: the maximum depth of the traversal.
+ * @v: a #GfsVariable.
+ * @v1: another #GfsVariable.
+ *
+ * Apply the boundary conditions of variable @v in @domain to variable @v1.
+ */
+void gfs_domain_copy_bc (GfsDomain * domain,
+			 FttTraverseFlags flags,
+			 gint max_depth,
+			 GfsVariable * v,
+			 GfsVariable * v1)
+{
+  BcData b = { flags, max_depth, v, v1, FTT_XYZ };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (v1 != NULL);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_start (domain, "bc");
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &b.c);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_stop (domain, "bc");
+}
+
+/**
+ * gfs_domain_bc:
+ * @domain: a #GfsDomain.
+ * @flags: the traversal flags.
+ * @max_depth: the maximum depth of the traversal.
+ * @v: a #GfsVariable.
+ *
+ * Apply the boundary conditions in @domain for variable @v.
+ */
+void gfs_domain_bc (GfsDomain * domain,
+		    FttTraverseFlags flags,
+		    gint max_depth,
+		    GfsVariable * v)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+
+  gfs_domain_copy_bc (domain, flags, max_depth, v, v);
+}
+
+static void box_homogeneous_bc (GfsBox * box, BcData * p)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) 
+    if (GFS_IS_BOUNDARY (box->neighbor[d])) {
+      GfsBoundary * b = GFS_BOUNDARY (box->neighbor[d]);
+      GfsBc * bc = gfs_boundary_lookup_bc (b, p->v);
+
+      if (bc) {
+	b->v = p->v1;
+	bc->v = p->v1;
+	b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+	ftt_face_traverse_boundary (b->root, b->d,
+				    FTT_PRE_ORDER, p->flags, p->max_depth,
+				    bc->homogeneous_bc, bc);
+	bc->v = p->v;
+	gfs_boundary_send (b);
+      }
+    }
+}
+
+/**
+ * gfs_domain_homogeneous_bc:
+ * @domain: a #GfsDomain.
+ * @flags: the traversal flags.
+ * @max_depth: the maximum depth of the traversal.
+ * @ov: a #GfsVariable.
+ * @v: a #GfsVariable of which @ov is an homogeneous version.
+ *
+ * Apply the boundary conditions in @domain for variable @ov using the
+ * homogeneous version of the boundary condititons for @v.
+ */
+void gfs_domain_homogeneous_bc (GfsDomain * domain,
+				FttTraverseFlags flags,
+				gint max_depth,
+				GfsVariable * ov,
+				GfsVariable * v)
+{
+  BcData b = { flags, max_depth, v, ov, FTT_XYZ };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (ov != NULL);
+  g_return_if_fail (v != NULL);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_start (domain, "bc");
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_homogeneous_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &b.c);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_stop (domain, "bc");
+}
+
+typedef struct {
+  FttCellTraverseFunc func;
+  gpointer data;
+  FttTraverseType order;
+  FttTraverseFlags flags;
+  gint max_depth;
+} TraverseData;
+
+typedef struct {
+  TraverseData t;
+  BcData b;
+} TraverseBcData;
+
+static void update_mpi_cell (FttCell * cell, TraverseData * p)
+{
+  if ((cell->flags & GFS_FLAG_USED) == 0) {
+    (* p->func) (cell, p->data);
+    cell->flags |= GFS_FLAG_USED;
+  }
+}
+
+static void update_other_cell (FttCell * cell, TraverseData * p)
+{
+  if ((cell->flags & GFS_FLAG_USED) != 0)
+    cell->flags &= ~GFS_FLAG_USED;
+  else
+    (* p->func) (cell, p->data);
+}
+
+static void update_mpi_boundaries (GfsBox * box, TraverseBcData * p)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) 
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundary * b = GFS_BOUNDARY (box->neighbor[d]);
+      GfsBc * bc = gfs_boundary_lookup_bc (b, p->b.v);
+
+      if (bc) {
+	ftt_cell_traverse_boundary (box->root, d, p->t.order, p->t.flags, p->t.max_depth,
+				    (FttCellTraverseFunc) update_mpi_cell, p);
+	b->v = p->b.v1;
+	bc->v = p->b.v1;
+	b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+	ftt_face_traverse_boundary (b->root, b->d,
+				    FTT_PRE_ORDER, p->b.flags, p->b.max_depth,
+				    bc->bc, bc);
+	bc->v = p->b.v;
+	gfs_boundary_send (b);
+      }
+    }
+}
+
+static void update_other_homogeneous_boundaries (GfsBox * box, BcData * p)
+{
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]) &&
+	!GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundary * b = GFS_BOUNDARY (box->neighbor[d]);
+      GfsBc * bc = gfs_boundary_lookup_bc (b, p->v);
+
+      if (bc) {
+	b->v = p->v1;
+	bc->v = p->v1;
+	b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+	ftt_face_traverse_boundary (b->root, b->d,
+				    FTT_PRE_ORDER, p->flags, p->max_depth,
+				    bc->homogeneous_bc, bc);
+	bc->v = p->v;
+	gfs_boundary_send (b);
+      }
+    }
+}
+
+/**
+ * gfs_traverse_and_homogeneous_bc:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @ov: a #GfsVariable.
+ * @v: a #GfsVariable of which @ov is an homogeneous version.
+ *
+ * For serial runs, this is identical to calling:
+ *
+ * gfs_domain_cell_traverse (domain, order, flags, max_depth, func, data);
+ * gfs_domain_homogeneous_bc (domain, flags, max_depth, ov, v);
+ *
+ * For parallel runs, the communications needed to apply the boundary
+ * conditions are overlapped with the calls to @func in the bulk of
+ * the domain.
+ */
+void gfs_traverse_and_homogeneous_bc (GfsDomain * domain,
+				      FttTraverseType order,
+				      FttTraverseFlags flags,
+				      gint max_depth,
+				      FttCellTraverseFunc func,
+				      gpointer data,
+				      GfsVariable * ov,
+				      GfsVariable * v)
+{
+  g_return_if_fail (domain != NULL);
+
+  if (domain->pid < 0 || !domain->overlap) {
+    gfs_domain_cell_traverse (domain, order, flags, max_depth, func, data);
+    gfs_domain_homogeneous_bc (domain, flags, max_depth, ov, v);
+  }
+  else {
+    TraverseBcData d = {
+      { func, data, order, flags, max_depth }, 
+      { flags, max_depth, v, ov, FTT_XYZ }
+    };
+    /* Update and send MPI boundary values */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) update_mpi_boundaries, &d);
+    /* Update bulk of domain and other boundaries */
+    gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+			      (FttCellTraverseFunc) update_other_cell, &d);
+    /* Apply homogeneous BC on other boundaries */
+    gts_container_foreach (GTS_CONTAINER (domain), 
+			   (GtsFunc) update_other_homogeneous_boundaries, &d.b);
+    /* Receive and synchronize */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &d.b);
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &d.b.c);
+  }
+}
+
+static void update_other_boundaries (GfsBox * box, BcData * p)
+{
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]) &&
+	!GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundary * b = GFS_BOUNDARY (box->neighbor[d]);
+      GfsBc * bc = gfs_boundary_lookup_bc (b, p->v);
+
+      if (bc) {
+	b->v = p->v1;
+	bc->v = p->v1;
+	b->type = GFS_BOUNDARY_CENTER_VARIABLE;
+	ftt_face_traverse_boundary (b->root, b->d,
+				    FTT_PRE_ORDER, p->flags, p->max_depth,
+				    bc->bc, bc);
+	bc->v = p->v;
+	gfs_boundary_send (b);
+      }
+    }
+}
+
+/**
+ * gfs_traverse_and_bc:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @v: a #GfsVariable.
+ * @v1: another #GfsVariable.
+ *
+ * For serial runs, this is identical to calling:
+ *
+ * gfs_domain_cell_traverse (domain, order, flags, max_depth, func, data);
+ * gfs_domain_copy_bc (domain, flags, max_depth, v, v1);
+ *
+ * For parallel runs, the communications needed to apply the boundary
+ * conditions are overlapped with the calls to @func in the bulk of
+ * the domain.
+ */
+void gfs_traverse_and_bc (GfsDomain * domain,
+			  FttTraverseType order,
+			  FttTraverseFlags flags,
+			  gint max_depth,
+			  FttCellTraverseFunc func,
+			  gpointer data,
+			  GfsVariable * v,
+			  GfsVariable * v1)
+{
+  g_return_if_fail (domain != NULL);
+
+  if (domain->pid < 0 || !domain->overlap) {
+    gfs_domain_cell_traverse (domain, order, flags, max_depth, func, data);
+    gfs_domain_copy_bc (domain, flags, max_depth, v, v1);
+  }
+  else {
+    TraverseBcData d = {
+      { func, data, order, flags, max_depth },
+      { flags, max_depth, v, v1, FTT_XYZ }
+    };
+    /* Update and send MPI boundary values */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) update_mpi_boundaries, &d);
+    /* Update bulk of domain and other boundaries */
+    gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+    			      (FttCellTraverseFunc) update_other_cell, &d);
+    /* Apply BC on other boundaries */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) update_other_boundaries, &d.b);
+    /* Receive and synchronize */
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &d.b);
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &d.b.c);
+  }
+}
+
+/**
+ * gfs_domain_face_bc:
+ * @domain: a #GfsDomain.
+ * @c: a component.
+ * @v: a #GfsVariable.
+ *
+ * Apply the boundary conditions on the faces of @domain for variable @v.
+ */
+void gfs_domain_face_bc (GfsDomain * domain,
+			 FttComponent c,
+			 GfsVariable * v)
+{
+  BcData b = { FTT_TRAVERSE_LEAFS, -1, v, v, c };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (c == FTT_XYZ || (c >= 0 && c < FTT_DIMENSION));
+  g_return_if_fail (v != NULL);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_start (domain, "face_bc");
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_face_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &b.c);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_stop (domain, "face_bc");
+}
+
+static void box_changed (GfsBox * box, gboolean * changed)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]))
+      *changed |= GFS_BOUNDARY (box->neighbor[d])->changed;
+}
+
+static void refine_cell_corner (FttCell * cell, GfsDomain * domain)
+{
+  if (ftt_refine_corner (cell))
+    ftt_cell_refine_single (cell, domain->cell_init, domain->cell_init_data);
+}
+
+static void box_depth (GfsBox * box, guint * depth)
+{
+  guint d = ftt_cell_depth (box->root);
+
+  if (d > *depth)
+    *depth = d;
+}
+
+static gboolean domain_match (GfsDomain * domain)
+{
+  BcData b = { FTT_TRAVERSE_LEAFS, -1, NULL, NULL, FTT_XYZ };
+  gboolean changed = FALSE;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_match, NULL);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_receive_bc, &b);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_synchronize, &b.c);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_changed, &changed);
+  if (changed) {
+    gint l;
+    guint depth = 0;
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_depth, &depth);
+    for (l = depth - 2; l >= 0; l--)
+      gfs_domain_cell_traverse (domain,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+				(FttCellTraverseFunc) refine_cell_corner, domain);
+  }
+  gfs_all_reduce (domain, changed, MPI_INT, MPI_MAX);
+  return changed;
+}
+
+/**
+ * gfs_domain_match:
+ * @domain: a #GfsDomain.
+ *
+ * Match the boundaries of @domain.
+ */
+void gfs_domain_match (GfsDomain * domain)
+{
+  g_return_if_fail (domain != NULL);
+
+  if (domain->profile_bc)
+    gfs_domain_timer_start (domain, "match");
+
+  while (domain_match (domain));
+
+  if (domain->profile_bc)
+    gfs_domain_timer_stop (domain, "match");
+}
+
+static void dirichlet_bc (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_DIRICHLET;
+  GFS_STATE (cell)->solid->fv = 0.;
+}
+
+static void neumann_bc (FttCell * cell)
+{
+  cell->flags &= ~GFS_FLAG_DIRICHLET;
+  GFS_STATE (cell)->solid->fv = 0.;
+}
+
+static gboolean is_velocity (GfsVariable * v, GfsDomain * domain)
+{
+  FttComponent c;
+  GfsVariable ** u = gfs_domain_velocity (domain);
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (v == u[c])
+      return TRUE;
+  return FALSE;
+}
+
+/**
+ * gfs_domain_surface_bc:
+ * @domain: a #GfsDomain.
+ * @v: a #GfsVariable.
+ *
+ * Apply boundary conditions for variable @v on embedded surfaces. 
+ */
+void gfs_domain_surface_bc (GfsDomain * domain,
+			    GfsVariable * v)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+
+  if (v->surface_bc)
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL,
+      (FttCellTraverseFunc) GFS_SURFACE_GENERIC_BC_CLASS (GTS_OBJECT (v->surface_bc)->klass)->bc, 
+			       v->surface_bc);
+  else if (is_velocity (v, domain))
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL,
+			       (FttCellTraverseFunc) dirichlet_bc, NULL);
+  else
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL,
+			       (FttCellTraverseFunc) neumann_bc, NULL);
+}
+
+static void box_traverse (GfsBox * box, TraverseData * d)
+{
+  ftt_cell_traverse (box->root, d->order, d->flags, d->max_depth, d->func, d->data);
+}
+
+/**
+ * gfs_domain_cell_traverse:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses the cell trees of @domain. Calls the given function for
+ * each cell visited.  
+ */
+void gfs_domain_cell_traverse (GfsDomain * domain,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       gint max_depth,
+			       FttCellTraverseFunc func,
+			       gpointer data)
+{
+  TraverseData d = { func, data, order, flags, max_depth };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_traverse, &d);
+}
+
+static void box_traverse_box (GfsBox * box, gpointer * datum)
+{
+  FttTraverseType * order = datum[0];
+  FttTraverseFlags * flags = datum[1];
+  gint * max_depth = datum[2];
+  FttCellTraverseFunc func = (FttCellTraverseFunc) datum[3];
+  gpointer data = datum[4];
+  GtsBBox * bb = datum[5];
+
+  ftt_cell_traverse_box (box->root, bb, 
+			 *order, *flags, *max_depth, func, data);
+}
+
+/**
+ * gfs_domain_cell_traverse_box:
+ * @domain: a #GfsDomain.
+ * @box: a #GtsBBox.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses the cell trees of @domain. Calls the given function for
+ * each cell visited. Only the cells overlapping with @box are visited.
+ */
+void gfs_domain_cell_traverse_box (GfsDomain * domain,
+				   GtsBBox * box,
+				   FttTraverseType order,
+				   FttTraverseFlags flags,
+				   gint max_depth,
+				   FttCellTraverseFunc func,
+				   gpointer data)
+{
+  gpointer datum[6];
+
+  datum[0] = &order;
+  datum[1] = &flags;
+  datum[2] = &max_depth;
+  datum[3] = func;
+  datum[4] = data;
+  datum[5] = box;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), 
+			 (GtsFunc) box_traverse_box, datum);
+}
+
+static void box_traverse_condition (GfsBox * box, gpointer * datum)
+{
+  FttTraverseType * order = datum[0];
+  FttTraverseFlags * flags = datum[1];
+  gint * max_depth = datum[2];
+  FttCellTraverseFunc func = (FttCellTraverseFunc) datum[3];
+  gpointer data = datum[4];
+  gboolean (* condition) (FttCell *, gpointer) = datum[5];
+  gpointer cdata = datum[6];
+
+  ftt_cell_traverse_condition (box->root, *order, *flags, *max_depth, func, data,
+			       condition, cdata);
+}
+
+/**
+ * gfs_domain_cell_traverse_condition:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @condition: the condition.
+ * @cdata: user data to pass to @condition.
+ *
+ * Traverses the cell trees of @domain. Calls the given function for
+ * each cell visited.
+ *
+ * Traversal of any branch of the tree is stopped whenever @condition
+ * is not verified.
+ */
+void gfs_domain_cell_traverse_condition (GfsDomain * domain,
+					 FttTraverseType order,
+					 FttTraverseFlags flags,
+					 gint max_depth,
+					 FttCellTraverseFunc func,
+					 gpointer data,
+					 gboolean (* condition) (FttCell *, gpointer),
+					 gpointer cdata)
+{
+  gpointer datum[7];
+
+  datum[0] = &order;
+  datum[1] = &flags;
+  datum[2] = &max_depth;
+  datum[3] = func;
+  datum[4] = data;
+  datum[5] = condition;
+  datum[6] = cdata;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (condition != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_traverse_condition, datum);
+}
+
+static void traverse_mixed (GfsBox * box, TraverseData * d)
+{
+  gfs_cell_traverse_mixed (box->root, d->order, d->flags, d->func, d->data);
+}
+
+/**
+ * gfs_domain_traverse_mixed:
+ * @domain: a #GfsDomain.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Calls @func for each mixed cell of @domain.
+ */
+void gfs_domain_traverse_mixed (GfsDomain * domain,
+				FttTraverseType order,
+				FttTraverseFlags flags,
+				FttCellTraverseFunc func,
+				gpointer data)
+{
+  TraverseData d = { func, data, order, flags, -1 };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) traverse_mixed, &d);
+}
+
+typedef struct {
+  FttCellTraverseCutFunc func;
+  gpointer data;
+  FttTraverseType order;
+  FttTraverseFlags flags;
+  GfsGenericSurface * s;
+} TraverseCut;
+
+static void traverse_cut (GfsBox * box, TraverseCut * p)
+{
+  gfs_cell_traverse_cut (box->root, p->s, p->order, p->flags, p->func, p->data);
+}
+
+/**
+ * gfs_domain_traverse_cut:
+ * @domain: a #GfsDomain.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Calls @func for each cell of @domain cut by @s.
+ */
+void gfs_domain_traverse_cut (GfsDomain * domain,
+			      GfsGenericSurface * s,
+			      FttTraverseType order,
+			      FttTraverseFlags flags,
+			      FttCellTraverseCutFunc func,
+			      gpointer data)
+{
+  TraverseCut p = { func, data, order, flags, s };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) traverse_cut, &p);
+}
+
+static void traverse_cut_2D (GfsBox * box, TraverseCut * p)
+{
+  gfs_cell_traverse_cut_2D (box->root, p->s, p->order, p->flags, p->func, p->data);
+}
+
+/**
+ * gfs_domain_traverse_cut_2D:
+ * @domain: a #GfsDomain.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Calls @func for each cell of @domain cut by @s.
+ *
+ * The cells are flattened in the z-direction.
+ */
+void gfs_domain_traverse_cut_2D (GfsDomain * domain,
+				 GfsGenericSurface * s,
+				 FttTraverseType order,
+				 FttTraverseFlags flags,
+				 FttCellTraverseCutFunc func,
+				 gpointer data)
+{
+  TraverseCut p = { func, data, order, flags, s };
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) traverse_cut_2D, &p);
+}
+
+/**
+ * gfs_domain_depth:
+ * @domain: a #GfsDomain.
+ *
+ * Returns: the maximum depth of the cell trees of @domain. This
+ * function is global i.e. it returns the maximum depth over all the
+ * processes (for parallel execution).
+ */
+guint gfs_domain_depth (GfsDomain * domain)
+{
+  guint depth = 0;
+
+  g_return_val_if_fail (domain != NULL, 0);
+
+  gts_container_foreach (GTS_CONTAINER (domain),
+			 (GtsFunc) box_depth, &depth);
+  gfs_all_reduce (domain, depth, MPI_UNSIGNED, MPI_MAX);
+  return depth;
+}
+
+#include "ftt_internal.c"
+
+/**
+ * gfs_domain_face_traverse:
+ * @domain: a #GfsDomain.
+ * @c: only the faces orthogonal to this component will be traversed - one of
+ * %FTT_X, %FTT_Y, (%FTT_Z), %FTT_XYZ.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children and faces are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCellFace.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a @domain. Calls the given function for each face
+ * of the cells of the domain.
+ *
+ * If %FTT_TRAVERSE_BOUNDARY_FACES is not set in @flags, only
+ * "double-sided" faces are traversed i.e. the @neighbor field of the
+ * face is never %NULL.  
+ */
+void gfs_domain_face_traverse (GfsDomain * domain,
+			       FttComponent c,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       gint max_depth,
+			       FttFaceTraverseFunc func,
+			       gpointer data)
+{
+  FttDirection d;
+  gpointer datum[6];
+  gboolean check = FALSE;
+  gboolean boundary_faces;
+  
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (c >= FTT_X && c <= FTT_XYZ);
+  g_return_if_fail (func != NULL);
+
+  boundary_faces = ((flags & FTT_TRAVERSE_BOUNDARY_FACES) != 0);
+  datum[1] = &max_depth;
+  datum[2] = func;
+  datum[3] = data;
+  datum[4] = &check;
+  datum[5] = &boundary_faces;
+  if (c == FTT_XYZ) {
+    if (boundary_faces) {
+      check = TRUE;
+      gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+	  (FttCellTraverseFunc) traverse_all_faces, 
+				datum);
+    }
+    else {
+      gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+	  (FttCellTraverseFunc) traverse_all_direct_faces, 
+				datum);
+      datum[0] = &d;
+      check = TRUE;
+      for (d = 1; d < FTT_NEIGHBORS; d += 2)
+	gfs_domain_cell_traverse_boundary (domain, 
+					   d, order, flags, max_depth, 
+					   (FttCellTraverseFunc) traverse_face, datum);
+    }
+  }
+  else if (c == FTT_XY) {
+    gfs_domain_face_traverse (domain, FTT_X, order, flags, max_depth, func, data);
+    gfs_domain_face_traverse (domain, FTT_Y, order, flags, max_depth, func, data);
+  }
+  else {
+    if (boundary_faces) {
+      check = TRUE;
+      datum[0] = &c;
+      gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+				(FttCellTraverseFunc) traverse_face_component,
+				datum);
+    }
+    else {
+      d = 2*c;
+      datum[0] = &d;
+      gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+				(FttCellTraverseFunc) traverse_face_direction, 
+				datum);
+      d = 2*c + 1;
+      check = TRUE;
+      gfs_domain_cell_traverse_boundary (domain, d, order, flags, max_depth, 
+					 (FttCellTraverseFunc) traverse_face, datum);
+    }
+  }
+  gfs_domain_cell_traverse (domain, order, flags, max_depth, 
+			    (FttCellTraverseFunc) reset_flag, NULL);
+}
+
+static void cell_traverse_boundary (GfsBox * box, gpointer * datum)
+{
+  FttDirection * d = datum[0];
+
+  if (!GFS_IS_BOX (box->neighbor[*d])) {
+    FttTraverseType * order = datum[1];
+    FttTraverseFlags * flags = datum[2];
+    gint * max_depth = datum[3];
+    FttCellTraverseFunc func = (FttCellTraverseFunc) datum[4];
+    gpointer data = datum[5];
+
+    ftt_cell_traverse_boundary (box->root, 
+				*d, *order, *flags, *max_depth, func, data);
+  }
+}
+
+/**
+ * gfs_domain_cell_traverse_boundary:
+ * @domain: a #GfsDomain.
+ * @d: the direction of the boundary to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses the boundary of a domain in direction @d. Calls the given
+ * function for each cell visited.  
+ */
+void gfs_domain_cell_traverse_boundary (GfsDomain * domain,
+					FttDirection d,
+					FttTraverseType order,
+					FttTraverseFlags flags,
+					gint max_depth,
+					FttCellTraverseFunc func,
+					gpointer data)
+{
+  gpointer datum[6];
+  
+  datum[0] = &d;
+  datum[1] = &order;
+  datum[2] = &flags;
+  datum[3] = &max_depth;
+  datum[4] = func;
+  datum[5] = data;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (d < FTT_NEIGHBORS);
+  g_return_if_fail (func != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) cell_traverse_boundary, datum);
+}
+
+static void add_stats (const FttCell * cell, gpointer * data)
+{
+  GtsRange * s = data[0];
+  gdouble v = GFS_VARIABLE (cell, GFS_VARIABLE1 (data[1])->i);
+
+  if (v < G_MAXDOUBLE)
+    gts_range_add_value (s, v);
+}
+
+#ifdef HAVE_MPI
+static void range_reduce (void * i, void * o, 
+			  int * len,
+			  MPI_Datatype * type)
+{
+  gdouble * in = (gdouble *) i;
+  gdouble * inout = (gdouble *) o;
+  g_assert (*len == 5);
+  
+  if (in[0] < inout[0]) /* min */
+    inout[0] = in[0];
+  if (in[1] > inout[1]) /* max */
+    inout[1] = in[1];
+  inout[2] += in[2];    /* sum */
+  inout[3] += in[3];    /* sum2 */
+  inout[4] += in[4];    /* n */
+}
+
+static void domain_range_reduce (GfsDomain * domain, GtsRange * s)
+{
+  if (domain->pid >= 0) {
+    double in[5];
+    double out[5] = { G_MAXDOUBLE, - G_MAXDOUBLE, 0., 0., 0. };
+    MPI_Op op;
+    
+    MPI_Op_create (range_reduce, TRUE, &op);
+    in[0] = s->min; in[1] = s->max; in[2] = s->sum; in[3] = s->sum2;
+    in[4] = s->n;
+    MPI_Allreduce (in, out, 5, MPI_DOUBLE, op, MPI_COMM_WORLD);
+    MPI_Op_free (&op);
+    s->min = out[0]; s->max = out[1]; s->sum = out[2]; s->sum2 = out[3];
+    s->n = out[4];
+  }
+}
+#else /* not HAVE_MPI */
+static void domain_range_reduce (GfsDomain * domain, GtsRange * s)
+{
+}
+#endif /* HAVE_MPI */
+
+/**
+ * gfs_domain_stats_variable:
+ * @domain: the domain to obtain statistics from.
+ * @v: a #GfsVariable.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Traverses the domain defined by @domain using gfs_domain_cell_traverse()
+ * and gathers statistics about variable @v.
+ *
+ * Returns: a #GtsRange containing the statistics about @v.
+ */
+GtsRange gfs_domain_stats_variable (GfsDomain * domain,
+				    GfsVariable * v,
+				    FttTraverseFlags flags,
+				    gint max_depth)
+{
+  GtsRange s;
+  gpointer data[2];
+
+  g_return_val_if_fail (domain != NULL, s);
+  g_return_val_if_fail (v != NULL, s);
+
+  gts_range_init (&s);
+  data[0] = &s;
+  data[1] = v;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			   (FttCellTraverseFunc) add_stats, data);
+  domain_range_reduce (domain, &s);
+  gts_range_update (&s);
+
+  return s;
+}
+
+static void add_stats_solid (FttCell * cell, GtsRange * s)
+{
+  gts_range_add_value (s, GFS_STATE (cell)->solid->a);
+}
+
+/**
+ * gfs_domain_stats_solid:
+ * @domain: the domain to obtain statistics from.
+ *
+ * Traverses the domain defined by @domain using gfs_domain_traverse_mixed()
+ * and gathers statistics about the solid volume fraction in mixed cells.
+ *
+ * Returns: statistics about the solid volume fraction @a in mixed cells.
+ */
+GtsRange gfs_domain_stats_solid (GfsDomain * domain)
+{
+  GtsRange s;
+
+  g_return_val_if_fail (domain != NULL, s);
+
+  gts_range_init (&s);
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			    (FttCellTraverseFunc) add_stats_solid, &s);
+  domain_range_reduce (domain, &s);
+  gts_range_update (&s);
+
+  return s;
+}
+
+static void add_stats_merged (GSList * m, gpointer * data)
+{
+  GtsRange * solid =  data[0];
+  GtsRange * number = data[1];
+  gdouble a = 0.;
+  guint n = 0;
+
+  while (m) {
+    FttCell * c = m->data;
+
+    a += GFS_IS_MIXED (c) ? GFS_STATE (c)->solid->a : 1.;
+    n++;
+    m = m->next;
+  }
+  if (n > 1 || a < 1.)
+    gts_range_add_value (solid, a);
+  if (n > 1)
+    gts_range_add_value (number, n);
+}
+
+/**
+ * gfs_domain_stats_merged:
+ * @domain: the domain to obtain statistics from.
+ * @solid: #GtsRange in which to return stats for the total solid
+ * volume fraction of merged cells. 
+ * @number: #GtsRange in which to return stats for the number of cells
+ * used per merged cell.
+ *
+ * Traverses the domain defined by @domain using
+ * gfs_domain_traverse_merged() and gathers statistics about the total
+ * solid volume fraction of merged cells and the number of cells used
+ * per merged cell.
+ */
+void gfs_domain_stats_merged (GfsDomain * domain,
+			     GtsRange * solid,
+			     GtsRange * number)
+{
+  gpointer data[2];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (solid != NULL);
+  g_return_if_fail (number != NULL);
+
+  gts_range_init (solid);
+  gts_range_init (number);
+  data[0] = solid;
+  data[1] = number;
+  gfs_domain_traverse_merged (domain,
+			     (GfsMergedTraverseFunc) add_stats_merged, data);
+  domain_range_reduce (domain, solid);
+  domain_range_reduce (domain, number);
+  gts_range_update (solid);
+  gts_range_update (number);
+}
+
+static void cell_count (FttCell * cell, guint * count)
+{
+  (*count)++;
+}
+
+#define BPID(b) (gfs_box_domain (b)->pid >= 0 && (b)->pid > 0 ? (b)->pid : 0)
+
+static void box_count (GfsBox * b, GArray * a)
+{
+  guint count = 0, pid = BPID(b);
+  ftt_cell_traverse (b->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		     (FttCellTraverseFunc) cell_count, &count);
+  if (pid >= a->len)
+    g_array_set_size (a, pid + 1);
+  g_array_index (a, guint, pid) += count;
+}
+
+static void boundary_size (GfsBox * box, GArray * a)
+{
+  FttDirection d;
+  guint count = 0;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d]) ||
+	(GFS_IS_BOX (box->neighbor[d]) && GFS_BOX (box->neighbor[d])->pid != box->pid))
+      ftt_cell_traverse_boundary (box->root, d, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) cell_count, &count);
+  g_array_index (a, guint, BPID (box)) += count;
+}
+
+/**
+ * gfs_domain_stats_balance:
+ * @domain: the domain to obtain statistics from.
+ * @size: #GtsRange in which to return stats for the total size of the domain.
+ * @boundary: #GtsRange in which to return stats for the size of the parallel 
+ * boundaries of the domain.
+ * @mpiwait:  #GtsRange in which to return stats for the average time spend
+ * waiting for MPI calls in each PE.
+ *
+ * Gathers statistics about the sizes of the domains, their parallel
+ * boundaries and the execution time on each PE.  
+ */
+void gfs_domain_stats_balance (GfsDomain * domain,
+			       GtsRange * size,
+			       GtsRange * boundary,
+			       GtsRange * mpiwait)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (size != NULL);
+  g_return_if_fail (boundary != NULL);
+  g_return_if_fail (mpiwait != NULL);
+
+  gts_range_init (size);
+  gts_range_init (boundary);
+  gts_range_init (mpiwait);
+
+  if (domain->timestep.n > 0)
+    gts_range_add_value (mpiwait, domain->mpi_wait.sum/domain->timestep.n);
+
+  GArray * a = g_array_new (FALSE, TRUE, sizeof (guint));
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_count, a);
+  guint i;
+  for (i = 0; i < a->len; i++) {
+    guint v = g_array_index (a, guint, i);
+    if (v > 0) {
+      gts_range_add_value (size, v);
+      g_array_index (a, guint, i) = 0;
+    }
+  }
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) boundary_size, a);
+  for (i = 0; i < a->len; i++) {
+    guint v = g_array_index (a, guint, i);
+    if (v > 0)
+      gts_range_add_value (boundary, v);
+  }
+  domain_range_reduce (domain, size);
+  domain_range_reduce (domain, boundary);
+  domain_range_reduce (domain, mpiwait);
+  g_array_free (a, TRUE);
+  gts_range_update (size);
+  gts_range_update (boundary);
+  gts_range_update (mpiwait);
+}
+
+static void add_norm (const FttCell * cell, gpointer * data)
+{
+  GfsNorm * n = data[0];
+  GfsVariable * v = data[1];
+
+  gfs_norm_add (n, GFS_VALUE (cell, v), gfs_cell_volume (cell, v->domain));
+}
+
+static void add_norm_weighted (FttCell * cell, gpointer * data)
+{
+  GfsNorm * n = data[0];
+  GfsVariable * v = data[1];
+  GfsFunction * w = data[2];
+
+  gfs_norm_add (n, GFS_VALUE (cell, v), gfs_cell_volume (cell, v->domain)*
+		gfs_function_value (w, cell));
+}
+
+#ifdef HAVE_MPI
+static void norm_reduce (void * i, void * o, 
+			 int * len,
+			 MPI_Datatype * type)
+{
+  gdouble * in = (gdouble *) i;
+  gdouble * inout = (gdouble *) o;
+  g_assert (*len == 5);
+  
+  inout[0] += in[0];    /* bias */
+  inout[1] += in[1];    /* first */
+  inout[2] += in[2];    /* second */
+  if (in[3] > inout[3]) /* infty */
+    inout[3] = in[3];    
+  inout[4] += in[4];    /* w */
+}
+
+static void domain_norm_reduce (GfsDomain * domain, GfsNorm * n)
+{
+  if (domain->pid >= 0) {
+    double in[5];
+    double out[5] = { 0., 0., 0., - G_MAXDOUBLE, 0. };
+    MPI_Op op;
+
+    MPI_Op_create (norm_reduce, TRUE, &op);
+    in[0] = n->bias; in[1] = n->first; in[2] = n->second; in[3] = n->infty;
+    in[4] = n->w;
+    MPI_Allreduce (in, out, 5, MPI_DOUBLE, op, MPI_COMM_WORLD);
+    MPI_Op_free (&op);
+    n->bias = out[0]; n->first = out[1]; n->second = out[2]; n->infty = out[3];
+    n->w = out[4];
+  }
+}
+#else /* not HAVE_MPI */
+static void domain_norm_reduce (GfsDomain * domain, GfsNorm * n)
+{
+}
+#endif /* not HAVE_MPI */
+
+/**
+ * gfs_domain_norm_variable:
+ * @domain: the domain to obtain norm from.
+ * @v: a #GfsVariable.
+ * @w: a #GfsFunction or %NULL.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Traverses the domain defined by @domain using gfs_domain_cell_traverse()
+ * and gathers norm statistics about variable @v.
+ *
+ * The norm is weighted by the volume of each cell times the value of
+ * function @w (if @w is not %NULL).
+ *
+ * Returns: a #GfsNorm containing the norm statistics about @v.
+ */
+GfsNorm gfs_domain_norm_variable (GfsDomain * domain,
+				  GfsVariable * v,
+				  GfsFunction * w,
+				  FttTraverseFlags flags,
+				  gint max_depth)
+{
+  GfsNorm n;
+  gpointer data[3];
+
+  g_return_val_if_fail (domain != NULL, n);
+  g_return_val_if_fail (v != NULL, n);
+  
+  gfs_norm_init (&n);
+  data[0] = &n;
+  data[1] = v;
+  data[2] = w;
+  if (w)
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			      (FttCellTraverseFunc) add_norm_weighted, data);
+  else
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			      (FttCellTraverseFunc) add_norm, data);
+  domain_norm_reduce (domain, &n);
+  gfs_norm_update (&n);
+
+  return n;
+}
+
+static void add_norm_residual (const FttCell * cell, gpointer * data)
+{
+  gdouble size = ftt_cell_size (cell);
+  GfsVariable * res = data[0];
+  GfsNorm * n = data[1];
+  
+  gfs_norm_add (n, GFS_VARIABLE (cell, res->i)/(size*size), 1.);
+}
+
+/**
+ * gfs_domain_norm_residual:
+ * @domain: the domain to obtain the norm from.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ * @dt: the time step.
+ * @res: the residual.
+ *
+ * Traverses the domain defined by @domain using gfs_domain_cell_traverse()
+ * and gathers norm statistics about the volume weighted relative residual
+ * (i.e. the sum of the residual over the volume defined by each cell
+ * divided by the total volume of the cell).
+ *
+ * Returns: a #GfsNorm containing the norm statistics about the volume
+ * weighted relative residual.  
+ */
+GfsNorm gfs_domain_norm_residual (GfsDomain * domain,
+				  FttTraverseFlags flags,
+				  gint max_depth,
+				  gdouble dt,
+				  GfsVariable * res)
+{
+  GfsNorm n;
+  gpointer data[2];
+
+  g_return_val_if_fail (domain != NULL, n);
+  g_return_val_if_fail (res != NULL, n);
+  
+  gfs_norm_init (&n);
+  data[0] = res;
+  data[1] = &n;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			   (FttCellTraverseFunc) add_norm_residual, data);
+  domain_norm_reduce (domain, &n);
+  gfs_norm_update (&n);
+
+  dt *= dt;
+  n.bias *= dt;
+  n.first *= dt;
+  n.second *= dt;
+  n.infty *= dt;
+  return n;
+}
+
+/**
+ * gfs_domain_velocity:
+ * @domain: a #GfsDomain.
+ *
+ * Returns: the components of the velocity vector for @domain.
+ */
+GfsVariable ** gfs_domain_velocity (GfsDomain * domain)
+{
+  FttComponent c;
+  static gchar name[][2] = {"U","V","W"};
+
+  g_return_val_if_fail (domain != NULL, NULL);
+  
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    GfsVariable * v = gfs_variable_from_name (domain->variables, name[c]);
+    g_return_val_if_fail (v != NULL, NULL);
+    domain->velocity[c] = v;
+  }
+  return domain->velocity;
+}
+
+static void add_norm_velocity (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** u = data[0];
+  GfsNorm * n = data[1];
+  
+  gfs_norm_add (n, gfs_vector_norm (cell, u), gfs_cell_volume (cell, u[0]->domain));
+}
+
+/**
+ * gfs_domain_norm_velocity:
+ * @domain: the domain to obtain the norm from.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Traverses the domain defined by @domain using gfs_domain_cell_traverse()
+ * and gathers norm statistics about velocity.
+ *
+ * Returns: a #GfsNorm containing the norm statistics about the velocity.
+ */
+GfsNorm gfs_domain_norm_velocity (GfsDomain * domain,
+				  FttTraverseFlags flags,
+				  gint max_depth)
+{
+  GfsNorm n;
+  gpointer data[2];
+
+  g_return_val_if_fail (domain != NULL, n);
+  
+  gfs_norm_init (&n);
+  data[0] = gfs_domain_velocity (domain);
+  data[1] = &n;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			   (FttCellTraverseFunc) add_norm_velocity, data);
+  domain_norm_reduce (domain, &n);
+  gfs_norm_update (&n);
+
+  return n;
+}
+
+/**
+ * gfs_domain_read:
+ * @fp: a #GtsFile.
+ *
+ * Reads the graph nodes (#GfsBox) and edges and the
+ * corresponding boundaries (#GfsBoundaryMpi if necessary) defined in
+ * @fp.
+ *
+ * Returns: the #GfsDomain or %NULL if an error occured, in which case
+ * the corresponding @fp fields (@pos and @error) are set.
+ */
+GfsDomain * gfs_domain_read (GtsFile * fp)
+{
+  GfsDomain * domain;
+
+  g_return_val_if_fail (fp != NULL, NULL);
+						 
+  if (!(domain = GFS_DOMAIN (gts_graph_read (fp))))
+    return NULL;
+
+  (* GFS_DOMAIN_CLASS (GTS_OBJECT (domain)->klass)->post_read) (domain, fp);
+  if (fp->type == GTS_ERROR) {
+    gts_object_destroy (GTS_OBJECT (domain));
+    return NULL;
+  }
+
+  return domain;
+}
+
+typedef struct {
+  GSList * boxlist;
+  guint bid;
+  gboolean one_box_per_pe;
+  gint pid;
+  GfsVariable * newboxp;
+  GfsDomain * domain;
+} SplitPar;
+
+static void box_split (GfsBox * box, SplitPar * p)
+{
+  guint refid = FTT_DIMENSION == 2 ? 2 : 6;
+  FttCellChildren child;
+  FttDirection d;
+  guint i;
+  GfsDomain * domain = gfs_box_domain (box);
+
+  p->boxlist = g_slist_prepend (p->boxlist, box);
+
+  if (FTT_CELL_IS_LEAF (box->root))
+    ftt_cell_refine_single (box->root, (FttCellInitFunc) gfs_cell_init, domain);
+
+  ftt_cell_children (box->root, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      GfsBox * newbox = GFS_BOX (gts_object_new (GTS_OBJECT (box)->klass));
+
+      GTS_OBJECT (newbox)->reserved = domain;
+      if (p->one_box_per_pe)
+	newbox->pid = (p->pid)++;
+      else
+	newbox->pid = box->pid;
+      if (box->id == 1 && i == refid)
+	newbox->id = 1;
+      else
+	newbox->id = (p->bid)++;
+
+      GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i)) = newbox;
+
+      if (FTT_CELL_IS_LEAF (child.c[i]))
+	ftt_cell_refine_single (child.c[i], (FttCellInitFunc) gfs_cell_init, domain);
+    }
+
+#if FTT_2D3
+  g_assert_not_implemented ();
+#endif
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d])) {
+      GfsBoundary * boundary = GFS_BOUNDARY (box->neighbor[d]);
+
+      ftt_cell_children (boundary->root, &child);
+      for (i = 0; i < FTT_CELLS; i++)
+	if (child.c[i] && FTT_CELL_IS_LEAF (child.c[i]))
+	  ftt_cell_refine_single (child.c[i], (FttCellInitFunc) gfs_cell_init, domain);
+      ftt_cell_destroy_root (boundary->root, &child, (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+      boundary->root = NULL;
+
+      ftt_cell_children_direction (box->root, d, &child);
+      for (i = 0; i < FTT_CELLS/2; i++)
+	if (child.c[i]) {
+	  FttCell * neighbor = ftt_cell_neighbor (child.c[i], d);
+	  GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i));
+	  GfsBoundaryClass * klass = GFS_BOUNDARY_CLASS (GTS_OBJECT (boundary)->klass);
+	  GtsObject * newboundary = GTS_OBJECT (gfs_boundary_new (klass, newbox, d));
+
+	  if (GFS_IS_BOUNDARY_PERIODIC (newboundary))
+	    GFS_BOUNDARY_PERIODIC (newboundary)->matching = 
+	      GFS_BOUNDARY_PERIODIC (boundary)->matching;
+	  else {
+	    gchar fname[] = "/tmp/XXXXXX";
+	    gint fd = mkstemp (fname);
+	    FILE * fp = fdopen (fd, "w");
+	    GtsFile * gfp;
+	    
+	    (* GTS_OBJECT_CLASS (klass)->write) (GTS_OBJECT (boundary), fp);
+	    fclose (fp);
+	    close (fd);
+	    fp = fopen (fname, "r");
+	    unlink (fname);
+	    gfp = gts_file_new (fp);
+	    (* GTS_OBJECT_CLASS (klass)->read) (&newboundary, gfp);
+	    g_assert (gfp->type != GTS_ERROR);
+	    gts_file_destroy (gfp);
+	    fclose (fp);
+	  }
+	  g_assert (neighbor);
+	  GFS_BOUNDARY (newboundary)->root = neighbor;
+	}
+      gts_object_destroy (GTS_OBJECT (boundary));
+    }
+}
+
+static GtsGEdge * node_is_linked (GtsGNode * n1, GtsGNode * n2, FttDirection d)
+{
+  GSList * i = GTS_SLIST_CONTAINER (n1)->items;
+  while (i) {
+    if (GTS_GNODE_NEIGHBOR (n1, i->data) == n2 &&
+	GFS_GEDGE (i->data)->d == d)
+      return i->data;
+    i = i->next;
+  }
+  return NULL;
+}
+
+static void box_link (GfsBox * box, SplitPar * p)
+{
+  FttCellChildren child;
+  guint i;
+
+  ftt_cell_children (box->root, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+       GfsBox * newbox = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], p->newboxp->i));
+       FttDirection d;
+       
+       g_assert (newbox);
+       gts_container_add (GTS_CONTAINER (p->domain), GTS_CONTAINEE (newbox));
+
+       for (d = 0; d < FTT_NEIGHBORS; d++)
+	 if (newbox->neighbor[d] != NULL && GFS_IS_BOUNDARY_PERIODIC (newbox->neighbor[d])) {
+	   GfsBox * matching =  GFS_BOUNDARY_PERIODIC (newbox->neighbor[d])->matching;
+	   static FttDirection match[FTT_CELLS][FTT_DIMENSION] = {
+#if FTT_2D
+	     {0,2}, {1,2}, {0,3}, {1,3}
+#elif FTT_2D3
+#else /* 3D */
+	     {0,2,4}, {1,2,4}, {0,3,4}, {1,3,4},
+	     {0,2,5}, {1,2,5}, {0,3,5}, {1,3,5}
+#endif /* 3D */
+	   };
+	   FttCell * neighbor = ftt_cell_child_corner (matching->root, 
+						       match[FTT_CELL_ID (child.c[i])]);
+	   g_assert (neighbor);
+	   GfsBox * newbox1 = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (neighbor, p->newboxp->i));
+	   g_assert (newbox1);
+	   GFS_BOUNDARY_PERIODIC (newbox->neighbor[d])->matching = newbox1;
+	   if (!node_is_linked (GTS_GNODE (newbox1), GTS_GNODE (newbox), 
+				FTT_OPPOSITE_DIRECTION (d))) {
+	     GfsGEdge * edge = GFS_GEDGE (gts_gedge_new (GTS_GRAPH (p->domain)->edge_class,
+							 GTS_GNODE (newbox), 
+							 GTS_GNODE (newbox1)));
+	     edge->d = d;
+	   }
+	 }
+	 else if (newbox->neighbor[d] == NULL) {
+	   FttCell * neighbor = ftt_cell_neighbor (child.c[i], d);
+
+	   if (neighbor) {
+	     GfsBox * newbox1 = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (neighbor, p->newboxp->i));
+	     FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	     GfsGEdge * edge;
+
+	     g_assert (newbox1);
+	     newbox->neighbor[d] = GTS_OBJECT (newbox1);
+	     g_assert (newbox1->neighbor[od] == NULL);
+	     newbox1->neighbor[od] = GTS_OBJECT (newbox);
+	     edge = GFS_GEDGE (gts_gedge_new (GTS_GRAPH (p->domain)->edge_class,
+					      GTS_GNODE (newbox), 
+					      GTS_GNODE (newbox1)));
+	     edge->d = d;
+	   }
+	 }
+    }
+}
+
+static void box_destroy (GfsBox * box, GfsVariable * newboxp)
+{
+  GfsBox * newbox[FTT_CELLS];
+  FttCellChildren child;
+  guint i;
+
+  ftt_cell_children (box->root, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i])
+      newbox[i] = GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (child.c[i], newboxp->i));
+    else
+      newbox[i] = NULL;
+
+  ftt_cell_destroy_root (box->root, &child, (FttCellCleanupFunc) gfs_cell_cleanup, 
+			 gfs_box_domain (box));
+  box->root = NULL;
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      newbox[i]->root = child.c[i];
+      FTT_ROOT_CELL (newbox[i]->root)->parent = newbox[i];
+    }
+
+  gts_object_destroy (GTS_OBJECT (box));
+}
+
+static void get_ref_pos (GfsBox * box, FttVector * pos)
+{
+  if (box->id == 1)
+    ftt_cell_pos (box->root, pos);
+}
+
+/**
+ * gfs_domain_split:
+ * @domain: a #GfsDomain.
+ * @one_box_per_pe: if %TRUE each new box created is assigned to a
+ * different process, otherwise the newly created box inherits the pid
+ * of its parent.
+ *
+ * Splits each box of @domain into its (4 in 2D, 8 in 3D)
+ * children. The corresponding newly created boxes are added to the
+ * graph and the parent boxes are destroyed.
+ */
+void gfs_domain_split (GfsDomain * domain, gboolean one_box_per_pe)
+{
+  SplitPar p;
+
+  g_return_if_fail (domain != NULL);
+
+  p.newboxp = gfs_temporary_variable (domain);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, 1,
+  			   (FttCellTraverseFunc) gfs_cell_reset, p.newboxp);
+  p.boxlist = NULL;
+  p.bid = 2;
+  p.pid = 0;
+  p.one_box_per_pe = one_box_per_pe;
+  p.domain = domain;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_split, &p);
+  g_slist_foreach (p.boxlist, (GFunc) box_link, &p);
+  g_slist_foreach (p.boxlist, (GFunc) box_destroy, p.newboxp);
+  g_slist_free (p.boxlist);
+  gts_object_destroy (GTS_OBJECT (p.newboxp));
+
+  gfs_domain_match (domain);
+  domain->rootlevel++;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) get_ref_pos, &domain->refpos);
+}
+
+/**
+ * gfs_domain_locate:
+ * @domain: a #GfsDomain.
+ * @target: position of the point to look for.
+ * @max_depth: maximum depth to consider (-1 means no restriction, see below for -2).
+ * @where: a pointer to a #GfsBox or %NULL.
+ *
+ * Locates the cell of @domain containing @target. This is done
+ * efficiently in log(n) operations by using the topology of the cell
+ * trees.
+ *
+ * If @max_depth is set to -2, the finest cell containing @target is
+ * returned. This cell is not necessarily a leaf-cell in contrast to
+ * the case where @max_depth is set to -1.
+ *
+ * If @where is not %NULL it is filled with the #GfsBox containing the
+ * cell.
+ *
+ * Returns: a #FttCell of @domain containing (boundary included) the
+ * point defined by @target or %NULL if @target is not contained in
+ * any cell of @domain.  
+ */
+FttCell * gfs_domain_locate (GfsDomain * domain,
+			     FttVector target,
+			     gint max_depth,
+			     GfsBox ** where)
+{
+  GtsObject * b = locate_array_locate (domain->array, &target);
+  if (GFS_IS_BOX (b)) {
+    if (where)
+      *where = GFS_BOX (b);
+    return ftt_cell_locate (GFS_BOX (b)->root, target, max_depth);
+  }
+  return NULL;
+}
+
+/**
+ * gfs_domain_boundary_locate:
+ * @domain: a #GfsDomain.
+ * @target: position of the point to look for.
+ * @max_depth: maximum depth to consider (-1 means no restriction).
+ * @where: a pointer to a #GtsObject.
+ *
+ * Locates the cell of @domain or of its boundary containing @target.
+ *
+ * If @where is not %NULL it is filled with the #GtsObject (either a
+ * #GfsBox or a #GfsBoundary) containing the cell.
+ *
+ * Returns: a #FttCell of @domain or of its boundary containing the
+ * point defined by @target or %NULL if @target is not contained in
+ * any cell of @domain or of its boundary.
+ */
+FttCell * gfs_domain_boundary_locate (GfsDomain * domain,
+				      FttVector target,
+				      gint max_depth,
+				      GtsObject ** where)
+{
+  GtsObject * b = locate_array_locate (domain->array, &target);
+  if (where)
+    *where = b;
+  if (GFS_IS_BOX (b))
+    return ftt_cell_locate (GFS_BOX (b)->root, target, max_depth);
+  else if (GFS_IS_BOUNDARY (b)) {
+    FttCell * cell = ftt_cell_locate (GFS_BOUNDARY (b)->root, target, max_depth);
+    return cell && GFS_CELL_IS_BOUNDARY (cell) ? cell : NULL;
+  }
+  return NULL;
+}
+
+static void box_distance2 (GfsBox * box, GPtrArray * a)
+{
+  g_ptr_array_add (a, box);
+}
+
+static void bubble_sort (GPtrArray * a, gdouble * d)
+{
+  guint i, j;
+
+  for (i = 0; i < a->len - 1; i++)
+    for (j = 0; j < a->len - 1 - i; j++)
+      if (d[j+1] < d[j]) {
+	gdouble tmp = d[j];
+	gpointer data = a->pdata[j];
+	d[j] = d[j+1];
+	d[j+1] = tmp;
+	a->pdata[j] = a->pdata[j+1];
+	a->pdata[j+1] = data;
+      }
+}
+
+/**
+ * gfs_domain_cell_point_distance2:
+ * @domain: a #GfsDomain.
+ * @p: a #GtsPoint.
+ * @distance2: the squared distance function.
+ * @data: user data to pass to @distance2.
+ * @closest: where to return the closest cell or %NULL.
+ *
+ * For non-leafs cells @distance2 must return a lower-bound for the
+ * minimum distance (using for example ftt_cell_point_distance2_min()).
+ *
+ * Returns: the square of the minimum distance measured according to
+ * @distance2 between @p and a leaf cell of @domain.
+ */
+gdouble gfs_domain_cell_point_distance2 (GfsDomain * domain,
+					 GtsPoint * p,
+					 gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+					 gpointer data,
+					 FttCell ** closest)
+{
+  gdouble dmin = G_MAXDOUBLE;
+  GPtrArray * a;
+  gdouble * d;
+  guint i;
+
+  g_return_val_if_fail (domain != NULL, dmin);
+  g_return_val_if_fail (p != NULL, dmin);
+  g_return_val_if_fail (distance2 != NULL, dmin);
+
+  if (closest)
+    *closest = NULL;
+  a = g_ptr_array_new ();
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_distance2, a);
+  d = g_malloc (sizeof (gdouble)*a->len);
+  for (i = 0; i < a->len; i++)
+    d[i] = (* distance2) (GFS_BOX (a->pdata[i])->root, p, data);
+  bubble_sort (a, d);
+  for (i = 0; i < a->len; i++)
+    if (d[i] < dmin)
+      ftt_cell_point_distance2_internal (GFS_BOX (a->pdata[i])->root, p, d[i],
+					 distance2, data, closest, &dmin);
+  g_free (d);
+  g_ptr_array_free (a, TRUE);
+  return dmin;
+}
+
+/**
+ * gfs_domain_advect_point:
+ * @domain: a #GfsDomain.
+ * @p: a #FttVector.
+ * @dt: the time step.
+ *
+ * Updates the coordinates of point @p at time t + @dt using the
+ * velocity field defined by @domain.
+ *
+ * If @p is not contained within @domain, the coordinates are unchanged.
+ */
+void gfs_domain_advect_point (GfsDomain * domain, 
+			      FttVector * p,
+			      gdouble dt)
+{
+  FttCell * cell;
+  FttVector p0, p1;
+  FttComponent c;
+  GfsVariable ** u;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+
+  p0 = p1 = *p;
+  cell = gfs_domain_locate (domain, p0, -1, NULL);
+  if (cell == NULL)
+    return;
+  u = gfs_domain_velocity (domain);
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&p1.x)[c] += dt*gfs_interpolate (cell, p0, u[c])/2.;
+  cell = gfs_domain_locate (domain, p1, -1, NULL);
+  if (cell == NULL)
+    return;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&p->x)[c] += dt*gfs_interpolate (cell, p1, u[c]);
+}
+
+static void count (FttCell * cell, guint * n)
+{
+  (*n)++;
+}
+
+/**
+ * gfs_domain_size:
+ * @domain: a #GfsDomain.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Returns: the number of cells of @domain traversed using @flags and
+ * @max_depth.
+ */
+guint gfs_domain_size (GfsDomain * domain,
+		       FttTraverseFlags flags,
+		       gint max_depth)
+{
+  guint n = 0;
+
+  g_return_val_if_fail (domain != NULL, 0);
+  
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			   (FttCellTraverseFunc) count, &n);
+  gfs_all_reduce (domain, n, MPI_UNSIGNED, MPI_SUM);
+  return n;
+}
+
+typedef struct {
+  gdouble cfl;
+  GfsVariable ** v;
+  GfsDomain * domain;
+} CflData;
+
+static void minimum_mac_cfl (FttCellFace * face, CflData * p)
+{
+  gdouble un = GFS_STATE (face->cell)->f[face->d].un;
+  gdouble length = ftt_cell_size (face->cell);
+  if (p->domain->cell_metric) {
+    gdouble fm = (* p->domain->face_metric) (p->domain, face);
+    if (fm <= 0.) /* e.g. Axi metric on the axis */
+      return;
+    length *= (* p->domain->cell_metric) (p->domain, face->cell)/fm;
+  }
+  if (un != 0.) {
+    gdouble cflu = length/fabs (un);
+    if (cflu*cflu < p->cfl)
+      p->cfl = cflu*cflu;
+  }
+  FttComponent c = face->d/2;
+  if (p->v[c]->sources) {
+    gdouble g = 0.;
+    GSList * i = GTS_SLIST_CONTAINER (p->v[c]->sources)->items;
+    while (i) {
+      GfsSourceGeneric * s = i->data;
+      if (s->face_value)
+	g += (* s->face_value) (s, face, p->v[c]);
+      i = i->next;
+    }
+    if (g != 0.) {
+      gdouble cflg = 2.*length/fabs (g);
+      if (cflg < p->cfl)
+	p->cfl = cflg;
+    }
+  }
+}
+
+static void minimum_cfl (FttCell * cell, CflData * p)
+{
+  gdouble length = ftt_cell_size (cell);
+  if (p->domain->cell_metric)
+    length *= (* p->domain->cell_metric) (p->domain, cell);
+
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble fm;
+    if (p->domain->face_metric) {
+      FttCellFace f;
+      f.cell = cell; f.d = 2*c;
+      gdouble fm1 = (* p->domain->face_metric) (p->domain, &f);
+      f.d = 2*c + 1;
+      gdouble fm2 = (* p->domain->face_metric) (p->domain, &f);
+      fm = MAX (fm1, fm2);
+    }
+    else
+      fm = 1.;
+    if (GFS_VALUE (cell, p->v[c]) != 0.) {
+      gdouble cflu = length/fabs (fm*GFS_VALUE (cell, p->v[c]));
+
+      if (cflu*cflu < p->cfl)
+	p->cfl = cflu*cflu;
+    }
+    if (p->v[c]->sources) {
+      gdouble g = gfs_variable_mac_source (p->v[c], cell);
+
+      if (g != 0.) {
+	gdouble cflg = 2.*length/fabs (fm*g);
+
+	if (cflg < p->cfl)
+	  p->cfl = cflg;
+      }
+    }
+  }
+}
+
+/**
+ * gfs_domain_cfl:
+ * @domain: a #GfsDomain.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Returns: the minimum over the cells of @domain (traversed using
+ * @flags and @max_depth) of the time scale defined by the size of the
+ * cell and the norm of either the local velocity or the local
+ * acceleration.
+ */
+gdouble gfs_domain_cfl (GfsDomain * domain,
+			FttTraverseFlags flags,
+			gint max_depth)
+{
+  CflData p;
+
+  g_return_val_if_fail (domain != NULL, 0.);
+
+  p.cfl = G_MAXDOUBLE;
+  p.v = gfs_domain_velocity (domain);
+  p.domain = domain;
+  gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, flags, max_depth, 
+			    (FttFaceTraverseFunc) minimum_mac_cfl, &p);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth, 
+			    (FttCellTraverseFunc) minimum_cfl, &p);
+  gfs_all_reduce (domain, p.cfl, MPI_DOUBLE, MPI_MIN);
+  return sqrt (p.cfl);
+}
+
+/**
+ * gfs_cell_init:
+ * @cell: a #FttCell.
+ * @domain: a #GfsDomain containing @cell.
+ *
+ * Allocates the memory for fluid state data associated to @cell or its children.
+ */
+void gfs_cell_init (FttCell * cell, GfsDomain * domain)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (domain != NULL);
+
+  if (FTT_CELL_IS_LEAF (cell)) {
+    g_return_if_fail (cell->data == NULL);
+    cell->data = g_malloc0 (gfs_domain_variables_size (domain));
+  }
+  else {
+    FttCellChildren child;
+    guint n;
+
+    ftt_cell_children (cell, &child);
+    for (n = 0; n < FTT_CELLS; n++) {
+      g_return_if_fail (child.c[n]->data == NULL);
+      child.c[n]->data = g_malloc0 (gfs_domain_variables_size (domain));
+    }
+    if (GFS_CELL_IS_BOUNDARY (cell))
+      for (n = 0; n < FTT_CELLS; n++)
+	child.c[n]->flags |= GFS_FLAG_BOUNDARY;
+  }
+}
+
+/**
+ * gfs_cell_reinit:
+ * @cell: a #FttCell.
+ * @domain: a #GfsDomain containing @cell.
+ *
+ * Re-allocates the memory for fluid state data associated to @cell.
+ */
+void gfs_cell_reinit (FttCell * cell, GfsDomain * domain)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (cell->data != NULL);
+  g_return_if_fail (domain != NULL);
+
+  cell->data = g_realloc (cell->data, gfs_domain_variables_size (domain));
+}
+
+/**
+ * gfs_cell_fine_init:
+ * @parent: a #FttCell.
+ * @domain: a #GfsDomain containing @parent.
+ *
+ * Initialises the children of @parent.
+ */
+void gfs_cell_fine_init (FttCell * parent, GfsDomain * domain)
+{
+  GSList * i;
+
+  g_return_if_fail (parent != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (parent));
+  g_return_if_fail (domain != NULL);
+
+  gfs_cell_init (parent, domain);
+
+  if (!GFS_CELL_IS_BOUNDARY (parent) && GFS_IS_MIXED (parent))
+    gfs_solid_coarse_fine (parent, domain);
+
+  /* metric is used by gfs_cell_coarse_fine(), make sure it is
+     initialised first */
+  i = domain->variables;
+  while (i) {
+    GfsVariable * v = i->data;
+    if (GFS_IS_VARIABLE_METRIC (v))
+      (* v->coarse_fine) (parent, v);
+    i = i->next;
+  }
+
+  /* initialise remaining variables */
+  i = domain->variables;
+  while (i) {
+    GfsVariable * v = i->data;
+    if (!GFS_IS_VARIABLE_METRIC (v))
+      (* v->coarse_fine) (parent, v);
+    i = i->next;
+  }
+}
+
+/**
+ * gfs_cell_copy:
+ * @from: a #FttCell to copy attributes from.
+ * @to: a #FttCell to copy attributes to.
+ * @domain: the #GfsDomain containing @from.
+ *
+ * Copies the attributes of the fluid cell @from to the fluid cell @to.
+ */
+void gfs_cell_copy (const FttCell * from, 
+		    FttCell * to,
+		    GfsDomain * domain)
+{
+  GfsSolidVector * solid;
+  GfsStateVector * froms, * tos;
+
+  g_return_if_fail (from != NULL);
+  g_return_if_fail (to != NULL);
+  g_return_if_fail (from != to);  
+  g_return_if_fail (domain != NULL);
+
+  froms = GFS_STATE (from);
+  tos = GFS_STATE (to);
+  if (froms != NULL) {
+    if (tos == NULL) {
+      gfs_cell_init (to, domain);
+      tos = GFS_STATE (to);
+    }
+    solid = tos->solid;
+    memcpy (to->data, from->data, gfs_domain_variables_size (domain));
+    if (froms->solid == NULL) {
+      if (solid)
+	g_free (solid);
+    }
+    else {
+      tos->solid = solid;
+      *solid = *(froms->solid);
+    }
+  }
+  else if (tos != NULL)
+    gfs_cell_cleanup (to, domain);
+}
+
+/**
+ * gfs_cell_write:
+ * @cell: a #FttCell.
+ * @fp: a file pointer.
+ * @variables: the list of #GfsVariable to be written.
+ *
+ * Writes in @fp the fluid data associated with @cell and described by
+ * @variables. This function is generally used in association with
+ * ftt_cell_write().  
+ */
+void gfs_cell_write (const FttCell * cell, FILE * fp,
+		     GSList * variables)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (GFS_IS_MIXED (cell)) {
+    GfsStateVector * s = GFS_STATE (cell);
+    guint i;
+
+    for (i = 0; i < FTT_NEIGHBORS; i++)
+      fprintf (fp, " %g", s->solid->s[i]);
+    fprintf (fp, " %g", s->solid->a);
+    for (i = 0; i < FTT_DIMENSION; i++)
+      fprintf (fp, " %g", (&s->solid->cm.x)[i]);
+  }
+  else
+    fputs (" -1", fp);
+  
+  while (variables) {
+    fprintf (fp, " %g", GFS_VARIABLE (cell, GFS_VARIABLE1 (variables->data)->i));
+    variables = variables->next;
+  }
+}
+
+/**
+ * gfs_cell_read:
+ * @cell: a #FttCell.
+ * @fp: a #GtsFile.
+ * @domain: the #GfsDomain containing @cell.
+ *
+ * Reads from @fp the fluid data associated with @cell and described
+ * by @domain->variables_io. This function is generally used in
+ * association with ftt_cell_read().  
+ */
+void gfs_cell_read (FttCell * cell, GtsFile * fp, GfsDomain * domain)
+{
+  gdouble s0;
+  GfsStateVector * s;
+  GSList * i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+  g_return_if_fail (domain != NULL);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (solid->s[0])");
+    return;
+  }
+  s0 = atof (fp->token->str);
+  if (s0 < 0. && s0 != -1.) {
+    gts_file_error (fp, "solid->s[0] must be positive");
+    return;
+  }
+  gts_file_next_token (fp);
+
+  gfs_cell_init (cell, domain);
+  s = cell->data;
+  if (s0 >= 0.) {
+    guint i;
+
+    s->solid = g_malloc0 (sizeof (GfsSolidVector));
+    s->solid->s[0] = s0;
+
+    for (i = 1; i < FTT_NEIGHBORS; i++) {
+      if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+	gts_file_error (fp, "expecting a number (solid->s[%d])", i);
+	return;
+      }
+      s->solid->s[i] = atof (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+      gts_file_error (fp, "expecting a number (solid->a)");
+      return;
+    }
+    s->solid->a = atof (fp->token->str);
+    gts_file_next_token (fp);
+    for (i = 0; i < FTT_DIMENSION; i++) {
+      if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+	gts_file_error (fp, "expecting a number (solid->cm[%d])", i);
+	return;
+      }
+      (&s->solid->cm.x)[i] = atof (fp->token->str);
+      gts_file_next_token (fp);
+    }
+  }
+
+  i = domain->variables_io;
+  while (i) {
+    GfsVariable * v = i->data;
+
+    if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+      gts_file_error (fp, "expecting a number (%s)", v->name);
+      return;
+    }
+    GFS_VARIABLE (cell, v->i) = atof (fp->token->str);
+    gts_file_next_token (fp);
+    i = i->next;
+  }
+}
+
+/**
+ * gfs_cell_write_binary:
+ * @cell: a #FttCell.
+ * @fp: a file pointer.
+ * @variables: the list of #GfsVariable to be written.
+ *
+ * Writes in @fp the fluid data associated with @cell and described by
+ * @variables. This function is generally used in association with
+ * ftt_cell_write_binary().
+ */
+void gfs_cell_write_binary (const FttCell * cell, FILE * fp,
+			    GSList * variables)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (GFS_IS_MIXED (cell)) {
+    GfsStateVector * s = GFS_STATE (cell);
+
+    fwrite (s->solid->s, sizeof (gdouble), FTT_NEIGHBORS, fp);
+    fwrite (&s->solid->a, sizeof (gdouble), 1, fp);
+    fwrite (&s->solid->cm.x, sizeof (gdouble), FTT_DIMENSION, fp);
+    fwrite (&s->solid->ca.x, sizeof (gdouble), FTT_DIMENSION, fp);
+  }
+  else {
+    gdouble a = -1.;
+    fwrite (&a, sizeof (gdouble), 1, fp);
+  }
+  
+  while (variables) {
+    gdouble a = GFS_VARIABLE (cell, GFS_VARIABLE1 (variables->data)->i);
+    fwrite (&a, sizeof (gdouble), 1, fp);
+    variables = variables->next;
+  }
+}
+
+/**
+ * gfs_cell_read_binary:
+ * @cell: a #FttCell.
+ * @fp: a #GtsFile.
+ * @domain: the #GfsDomain containing @cell.
+ *
+ * Reads from @fp the fluid data associated with @cell and described
+ * by @domain->variables_io. This function is generally used in
+ * association with ftt_cell_read_binary().
+ */
+void gfs_cell_read_binary (FttCell * cell, GtsFile * fp, GfsDomain * domain)
+{
+  gdouble s0;
+  GfsStateVector * s;
+  GSList * i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+  g_return_if_fail (domain != NULL);
+
+  if (gts_file_read (fp, &s0, sizeof (gdouble), 1) != 1) {
+    gts_file_error (fp, "expecting a number (solid->s[0])");
+    return;
+  }
+  if (s0 < 0. && s0 != -1.) {
+    gts_file_error (fp, "solid->s[0] must be positive");
+    return;
+  }
+
+  gfs_cell_init (cell, domain);
+  s = cell->data;
+  if (s0 >= 0.) {
+    s->solid = g_malloc0 (sizeof (GfsSolidVector));
+    s->solid->s[0] = s0;
+    
+    if (gts_file_read (fp, &s->solid->s[1], sizeof (gdouble), FTT_NEIGHBORS - 1) 
+	!= FTT_NEIGHBORS - 1) {
+      gts_file_error (fp, "expecting numbers (solid->s[1..%d])", FTT_NEIGHBORS - 1);
+      return;
+    }
+    if (gts_file_read (fp, &s->solid->a, sizeof (gdouble), 1) != 1) {
+      gts_file_error (fp, "expecting a number (solid->a)");
+      return;
+    }
+    if (gts_file_read (fp, &s->solid->cm.x, sizeof (gdouble), FTT_DIMENSION) != FTT_DIMENSION) {
+      gts_file_error (fp, "expecting numbers (solid->cm[0..%d])", FTT_DIMENSION - 1);
+      return;
+    }
+    if (domain->version >= 90628 &&
+	gts_file_read (fp, &s->solid->ca.x, sizeof (gdouble), FTT_DIMENSION) != FTT_DIMENSION) {
+      gts_file_error (fp, "expecting numbers (solid->ca[0..%d])", FTT_DIMENSION - 1);
+      return;
+    }
+  }
+
+  i = domain->variables_io;
+  while (i) {
+    GfsVariable * v = i->data;
+    gdouble a;
+
+    if (gts_file_read (fp, &a, sizeof (gdouble), 1) != 1) {
+      gts_file_error (fp, "expecting a number (%s)", v->name);
+      return;
+    }
+    GFS_VARIABLE (cell, v->i) = a;
+    i = i->next;
+  }
+}
+
+static void box_realloc (GfsBox * box, GfsDomain * domain)
+{
+  FttDirection d;
+
+  ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) gfs_cell_reinit, domain);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY (box->neighbor[d]))
+      ftt_cell_traverse (GFS_BOUNDARY (box->neighbor[d])->root, 
+			 FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			 (FttCellTraverseFunc) gfs_cell_reinit, domain);
+}
+
+/**
+ * gfs_domain_alloc:
+ * @domain: a #GfsDomain.
+ *
+ * Returns: the index of a memory location newly allocated for each
+ * cell of @domain.
+ */
+guint gfs_domain_alloc (GfsDomain * domain)
+{
+  guint i = 0;
+
+  g_return_val_if_fail (domain != NULL, -1);
+
+  while (i < domain->allocated->len && g_array_index (domain->allocated, gboolean, i))
+    i++;
+  if (i == domain->allocated->len) {
+    g_array_set_size (domain->allocated, domain->allocated->len + 1);
+    gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) box_realloc, domain);
+  }
+  g_array_index (domain->allocated, gboolean, i) = TRUE;
+  return i;
+}
+
+/**
+ * gfs_domain_free:
+ * @domain: a #GfsDomain.
+ * @i: a memory location index previously allocated using gfs_domain_alloc().
+ *
+ * Frees the memory location of @domain defined by @i.
+ */
+void gfs_domain_free (GfsDomain * domain, guint i)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (i < domain->allocated->len);
+  g_return_if_fail (g_array_index (domain->allocated, gboolean, i));
+
+  g_array_index (domain->allocated, gboolean, i) = FALSE;
+}
+
+/**
+ * gfs_domain_add_variable:
+ * @domain: a #GfsDomain.
+ * @name: the name of the variable to add or %NULL.
+ * @description: the variable description or %NULL.
+ *
+ * Adds a new variable @name to @domain.
+ *
+ * Returns: the new variable or %NULL if a variable with the same name
+ * already exists.  
+ */
+GfsVariable * gfs_domain_add_variable (GfsDomain * domain,
+				       const gchar * name,
+				       const gchar * description)
+{
+  GfsVariable * v;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+
+  if ((v = gfs_variable_new (gfs_variable_class (), domain, name, description)) == NULL)
+    return NULL;
+  domain->variables = g_slist_append (domain->variables, v);
+  return v;
+}
+
+/**
+ * gfs_domain_get_or_add_variable:
+ * @domain: a #GfsDomain.
+ * @name: the name of the variable to add or get.
+ * @description: the variable description or %NULL.
+ *
+ * Adds a new variable @name to @domain or returns the variable of
+ * @domain with the same name. In either case the description of the
+ * variable name is set to @description (if it is not %NULL).
+ *
+ * Returns: the new or already existing variable or %NULL if @name is a
+ * reserved variable name.
+ */
+GfsVariable * gfs_domain_get_or_add_variable (GfsDomain * domain,
+					      const gchar * name,
+					      const gchar * description)
+{
+  GfsVariable * v;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  v = gfs_variable_from_name (domain->variables, name);
+  if (v != NULL) {
+    if (description) {
+      if (v->description)
+	g_free (v->description);
+      v->description = g_strdup (description);
+    }
+  }
+  else
+    v = gfs_domain_add_variable (domain, name, description);
+  return v;
+}
+
+static void add_pressure_force (FttCell * cell, gpointer * data)
+{
+  gdouble weight = data[3] ? gfs_function_value (data[3], cell) : 1.;
+
+  if (weight != 0.) {
+    gdouble * f = data[0];
+    gdouble * m = data[1];
+    gdouble * r = &GFS_STATE (cell)->solid->ca.x;
+    GfsVariable * p = data[2];
+    FttVector ff, mm;
+    FttComponent c;
+    
+    gfs_pressure_force (cell, p, &ff);
+    gts_vector_cross (&mm.x, r, &ff.x);
+    for (c = 0; c < 3; c++) {
+      f[c] += weight*(&ff.x)[c];
+      m[c] += weight*(&mm.x)[c];
+    }
+  }
+}
+
+static GfsSourceDiffusion * source_diffusion (GfsVariable * v)
+{
+  if (v->sources) {
+    GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+    
+    while (i) {
+      GtsObject * o = i->data;
+      
+      if (GFS_IS_SOURCE_DIFFUSION (o))
+	return GFS_SOURCE_DIFFUSION (o);
+      i = i->next;
+    }
+  }
+  return NULL;
+}
+
+static void add_viscous_force (FttCell * cell, gpointer * data)
+{
+  gdouble weight = data[4] ? gfs_function_value (data[4], cell) : 1.;
+
+  if (weight != 0.) {
+    gdouble * f = data[0];
+    gdouble * m = data[1];
+    GfsVariable * v = data[2];
+    GfsSourceDiffusion * d = data[3];
+    gdouble D;
+    GfsSolidVector * s = GFS_STATE (cell)->solid;
+    gdouble * r = &s->ca.x;
+    FttVector ff, mm, n, g;
+    FttComponent c;
+    
+    g_assert (((cell)->flags & GFS_FLAG_DIRICHLET) != 0);
+    gfs_cell_dirichlet_gradient (cell, v->i, -1, s->fv, &g);
+    
+    D = - gfs_source_diffusion_cell (d, cell);
+    n.x = s->s[1] - s->s[0];
+    n.y = s->s[3] - s->s[2];
+#if FTT_2D
+    ff.z = 0.;
+    switch (v->component) {
+    case FTT_X:
+      ff.x = D*(2.*g.x*n.x + g.y*n.y);
+      ff.y = D*g.y*n.x;
+      break;
+    case FTT_Y:
+      ff.x = D*g.x*n.y;
+      ff.y = D*(2.*g.y*n.y + g.x*n.x);
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+#else /* 3D */
+    n.z = s->s[5] - s->s[4];
+    D *= ftt_cell_size (cell);
+    switch (v->component) {
+    case FTT_X:
+      ff.x = D*(2.*g.x*n.x + g.y*n.y + g.z*n.z);
+      ff.y = D*g.y*n.x;
+      ff.z = D*g.z*n.x;
+      break;
+    case FTT_Y:
+      ff.y = D*(2.*g.y*n.y + g.x*n.x + g.z*n.z);
+      ff.x = D*g.x*n.y;
+      ff.z = D*g.z*n.y;
+      break;
+    case FTT_Z:
+      ff.z = D*(2.*g.z*n.z + g.x*n.x + g.y*n.y);
+      ff.x = D*g.x*n.z;
+      ff.y = D*g.y*n.z;
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+#endif /* 3D */
+    gts_vector_cross (&mm.x, r, &ff.x);
+    for (c = 0; c < 3; c++) {
+      f[c] += weight*(&ff.x)[c];
+      m[c] += weight*(&mm.x)[c];
+    }
+  }
+}
+
+/**
+ * gfs_domain_solid_force:
+ * @domain: a #GfsDomain.
+ * @pf: a #FttVector.
+ * @vf: a #FttVector.
+ * @pm: a #FttVector.
+ * @vm: a #FttVector.
+ * @weight: an optional weight.
+ *
+ * Fills @pf and @vf (resp. @pm and @vm) with the components of the
+ * net pressure and viscous forces (resp. pressure and viscous
+ * moments) applied by the fluid on the solid surface embedded in
+ * @domain.
+ *
+ * The reference point for the moments is the origin of the coordinate system.
+ */
+void gfs_domain_solid_force (GfsDomain * domain, 
+			     FttVector * pf,
+			     FttVector * vf,
+			     FttVector * pm,
+			     FttVector * vm,
+			     GfsFunction * weight)
+{
+  FttComponent c;
+  GfsVariable ** v;
+  gpointer data[4];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (pf != NULL);
+  g_return_if_fail (vf != NULL);
+  g_return_if_fail (pm != NULL);
+  g_return_if_fail (vm != NULL);
+
+  if (GFS_IS_AXI (domain))
+    g_assert_not_implemented ();
+
+  pf->x = pf->y = pf->z = 0.;
+  pm->x = pm->y = pm->z = 0.;
+  data[0] = pf;
+  data[1] = pm;
+  data[2] = gfs_variable_from_name (domain->variables, "P");
+  data[3] = weight;
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseFunc) add_pressure_force, data);
+
+  vf->x = vf->y = vf->z = 0.;
+  vm->x = vm->y = vm->z = 0.;
+  v = gfs_domain_velocity (domain);
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    GfsSourceDiffusion * D = source_diffusion (v[c]);
+
+    if (D) {
+      gpointer data[5];
+
+      gfs_domain_surface_bc (domain, v[c]);
+      data[0] = vf;
+      data[1] = vm;
+      data[2] = v[c];
+      data[3] = D;
+      data[4] = weight;
+      gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				 (FttCellTraverseFunc) add_viscous_force, data);
+    }
+  }
+}
+
+#define THRESHOLD 1e-4
+
+static void tag_cell_fraction (GtsFifo * fifo,
+			       FttCell * cell,
+			       GfsVariable * c, GfsVariable * v,
+			       guint tag)
+{
+  FttDirection d;
+  FttCellNeighbors n;
+
+  g_assert (FTT_CELL_IS_LEAF (cell));
+  ftt_cell_neighbors (cell, &n);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (n.c[d] && GFS_VALUE (n.c[d], v) == 0. && GFS_VALUE (n.c[d], c) > THRESHOLD) {
+      if (FTT_CELL_IS_LEAF (n.c[d])) {
+	GFS_VALUE (n.c[d], v) = tag;
+	gts_fifo_push (fifo, n.c[d]);
+      }
+      else {
+	FttCellChildren child;
+	FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	guint i;
+
+#if FTT_2D3
+	g_assert_not_implemented ();
+#endif	
+	ftt_cell_children_direction (n.c[d], od, &child);
+	for (i = 0; i < FTT_CELLS/2; i++)
+	  if (child.c[i] && GFS_VALUE (child.c[i], v) == 0. &&
+	      GFS_VALUE (child.c[i], c) > THRESHOLD) {
+	    GFS_VALUE (child.c[i], v) = tag;
+	    gts_fifo_push (fifo, child.c[i]);
+	  }
+      }
+    }
+}
+
+typedef struct {
+  GfsVariable * v, * c;
+  FttDirection d;
+  guint * touch, * tags, tag, tagshift;
+} TagPar;
+
+static void tag_new_fraction_region (FttCell * cell, TagPar * p)
+{
+  if (GFS_VALUE (cell, p->v) == 0. && GFS_VALUE (cell, p->c) > THRESHOLD) {
+    GtsFifo * fifo = gts_fifo_new ();
+
+    GFS_VALUE (cell, p->v) = ++p->tag;
+    gts_fifo_push (fifo, cell);
+    while ((cell = gts_fifo_pop (fifo)))
+      tag_cell_fraction (fifo, cell, p->c, p->v, p->tag);
+    gts_fifo_destroy (fifo);
+  }
+}
+
+/* @touch defines the touching connectivity. This function updates
+   @touch with the info that region tagged with @tag1 touches the
+   region tagged with @tag2  */
+static void touching_regions (guint tag1, guint tag2, guint * touch)
+{
+  if (tag2 < tag1) {
+    guint tmp = tag1;
+    tag1 = tag2;
+    tag2 = tmp;
+  }
+  else if (tag2 == tag1)
+    return;
+  guint ntag = touch[tag2];
+  if (ntag == tag1)
+    return;
+  if (ntag == 0)
+    touch[tag2] = tag1;
+  else {
+    if (tag1 < ntag)
+      touch[tag2] = tag1;
+    touching_regions (tag1, ntag, touch);
+  }
+}
+
+#ifdef HAVE_MPI
+static void reduce_touching_regions (void * in, void * inout, int * len, MPI_Datatype * type)
+{
+  guint * ltouch = (guint *) in;
+  guint * gtouch = (guint *) inout;
+  guint i;
+
+  for (i = 1; i < *len; i++)
+    if (ltouch[i] > 0)
+      touching_regions (i, ltouch[i], gtouch);
+}
+
+static void shift_tags (FttCell * cell, TagPar * p)
+{
+  if (GFS_VALUE (cell, p->v) > 0.)
+    GFS_VALUE (cell, p->v) += p->tagshift;
+}
+#endif /* HAVE_MPI */
+
+static void unify_tag_range (GfsDomain * domain, TagPar * p)
+{
+#ifdef HAVE_MPI
+  if (domain->pid >= 0) {
+    int gsize;
+    guint * tags;
+    MPI_Comm_size (MPI_COMM_WORLD, &gsize);
+    tags = g_malloc (sizeof (guint)*gsize);
+    tags[domain->pid] = p->tag;
+    MPI_Allgather (&tags[domain->pid], 1, MPI_UNSIGNED, tags, 1, MPI_UNSIGNED, MPI_COMM_WORLD);
+    /* tags[] now contains the p->tag value on each PE */
+    guint i;
+    p->tag = 0;
+    for (i = 0; i < gsize; i++)
+      p->tag += tags[i];
+    /* shift tag values to get a single tag space across all PEs */
+    if (domain->pid > 0) {
+      p->tagshift = 0;
+      for (i = 0; i < domain->pid; i++)
+	p->tagshift += tags[i];
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) shift_tags, p);
+    }
+    g_free (tags);
+  }
+#endif /* HAVE_MPI */
+}
+
+static void match_periodic_bc (FttCell * cell, TagPar * p)
+{
+  guint tag = GFS_VALUE (cell, p->v);
+  if (tag > 0) {
+    FttCell * neighbor = ftt_cell_neighbor (cell, p->d);
+    guint ntag = GFS_VALUE (neighbor, p->v);
+    if (ntag > 0)
+      touching_regions (tag, ntag, p->touch);
+  }
+}
+
+static void match_box_bc (GfsBox * box, TagPar * p)
+{
+  for (p->d = 0; p->d < FTT_NEIGHBORS; p->d++)
+    if (GFS_IS_BOUNDARY_PERIODIC (box->neighbor[p->d]))
+      ftt_cell_traverse_boundary (box->root, p->d, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) match_periodic_bc, p);
+}
+
+static void fix_touching (FttCell * cell, TagPar * p)
+{
+  GFS_VALUE (cell, p->v) = p->tags[p->touch[(guint) GFS_VALUE (cell, p->v)]];
+}
+
+/**
+ * gfs_domain_tag_droplets:
+ * @domain: a #GfsDomain.
+ * @c: the volume fraction.
+ * @tag: a #GfsVariable.
+ *
+ * Fills the @tag variable of the cells of @domain with the (strictly
+ * positive) index of the droplet they belong to. The cells belonging
+ * to the background phase have an index of zero.
+ *
+ * Note that the volume fraction @c must be defined on all levels.
+ *
+ * Returns: the number of droplets.
+ */
+guint gfs_domain_tag_droplets (GfsDomain * domain,
+			       GfsVariable * c,
+			       GfsVariable * tag)
+{
+  g_return_val_if_fail (domain != NULL, 0);
+  g_return_val_if_fail (c != NULL, 0);
+  g_return_val_if_fail (tag != NULL, 0);
+
+  TagPar p;
+  gboolean touching = FALSE;
+  p.c = c;
+  p.v = tag;
+  p.tag = 0;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, tag);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) tag_new_fraction_region, &p);
+
+  /* the rest of the algorithm deals with periodic and parallel BCs */
+  unify_tag_range (domain, &p);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, tag);
+  p.touch = g_malloc0 ((p.tag + 1)*sizeof (guint));
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) match_box_bc, &p);
+
+#ifdef HAVE_MPI
+  if (domain->pid >= 0) {
+    guint * gtouch = g_malloc0 ((p.tag + 1)*sizeof (guint));
+    MPI_Op op;    
+    MPI_Op_create (reduce_touching_regions, TRUE, &op);
+    MPI_Allreduce (p.touch, gtouch, p.tag + 1, MPI_UNSIGNED, op, MPI_COMM_WORLD);
+    MPI_Op_free (&op);
+    g_free (p.touch);
+    p.touch = gtouch;
+  }
+#endif /* HAVE_MPI */
+  
+  /* find region with smallest tag touching each region i.e. reduces
+     the chain of touching tags */
+  guint i, maxtag = 0;
+  for (i = 1; i <= p.tag; i++) {
+    guint touch = p.touch[i];
+    while (touch > 0) {
+      p.touch[i] = touch;
+      touch = p.touch[touch];
+      touching = TRUE;
+    }
+    if (p.touch[i] == 0 && i > maxtag)
+      maxtag = i;
+  }
+  
+  /* fix touching regions */
+  if (touching) {
+    guint ntag = 0; /* fresh tag index */
+    p.tags = g_malloc ((maxtag + 1)*sizeof (guint));
+    p.tags[0] = 0;
+    for (i = 1; i <= maxtag; i++)
+      if (p.touch[i] == 0) { /* this region is not touching any other */
+	p.touch[i] = i;
+	p.tags[i] = ++ntag;
+      }
+    maxtag = ntag;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) fix_touching, &p);
+    g_free (p.tags);
+  }
+
+  g_free (p.touch);
+  return maxtag;
+}
+
+typedef struct {
+  GfsVariable * tag, * c;
+  guint * sizes;
+  guint n, min;
+} RemoveDropletsPar;
+
+static void compute_droplet_size (FttCell * cell, RemoveDropletsPar * p)
+{
+  guint i = GFS_VALUE (cell, p->tag);
+  if (i > 0)
+    p->sizes[i - 1]++;
+}
+
+static void reset_small_fraction (FttCell * cell, RemoveDropletsPar * p)
+{
+  guint i = GFS_VALUE (cell, p->tag);
+  if (i > 0 && p->sizes[i - 1] < p->min)
+    GFS_VALUE (cell, p->c) = 0.;
+}
+
+static int greater (const void * a, const void * b)
+{
+  return *((guint *)a) > *((guint *)b) ? -1 : 1;
+}
+
+/**
+ * gfs_domain_remove_droplets:
+ * @domain: a #GfsDomain.
+ * @c: a #GfsVariable.
+ * @v: a #GfsVariable.
+ * @min: the minimum size (in cells) of the droplets.
+ *
+ * Resets the @v variable of all the droplets (defined by the @c
+ * variable) smaller than @min cells if @min is positive, or all the
+ * droplets but the -$min largest ones if @min is negative.
+ */
+void gfs_domain_remove_droplets (GfsDomain * domain,
+				 GfsVariable * c,
+				 GfsVariable * v,
+				 gint min)
+{
+  RemoveDropletsPar p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (c != NULL);
+  g_return_if_fail (v != NULL);
+
+  p.c = c;
+  p.tag = gfs_temporary_variable (domain);
+  p.n = gfs_domain_tag_droplets (domain, c, p.tag);
+  if (p.n > 0 && -min < (gint) p.n) {
+    p.sizes = g_malloc0 (p.n*sizeof (guint));
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) compute_droplet_size, &p);
+#ifdef HAVE_MPI
+    if (domain->pid >= 0) {
+      guint * sizes = g_malloc0 (p.n*sizeof (guint));
+      MPI_Allreduce (p.sizes, sizes, p.n, MPI_UNSIGNED, MPI_SUM, MPI_COMM_WORLD);
+      g_free (p.sizes);
+      p.sizes = sizes;
+    }
+#endif
+    if (min >= 0)
+      p.min = min;
+    else {
+      guint * tmp = g_malloc (p.n*sizeof (guint));
+      memcpy (tmp, p.sizes, p.n*sizeof (guint));
+      qsort (tmp, p.n, sizeof (guint), greater);
+      g_assert (-1 - min < p.n);
+      p.min = tmp[-1 - min];
+      g_free (tmp);
+    }
+    p.c = v;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) reset_small_fraction, &p);
+    g_free (p.sizes);
+  }
+  gts_object_destroy (GTS_OBJECT (p.tag));
+}
+
+static void tag_cell (FttCell * cell, GfsVariable * v, guint tag, guint * size)
+{
+  FttDirection d;
+  FttCellNeighbors n;
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+  g_assert (FTT_CELL_IS_LEAF (cell));
+  GFS_VARIABLE (cell, v->i) = tag;
+  (*size)++;
+  ftt_cell_neighbors (cell, &n);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (n.c[d] && GFS_VARIABLE (n.c[d], v->i) == 0. &&
+	!GFS_CELL_IS_BOUNDARY (n.c[d]) &&
+	(!solid || solid->s[d] > 0.)) {
+      if (FTT_CELL_IS_LEAF (n.c[d]))
+	tag_cell (n.c[d], v, tag, size);
+      else {
+	FttCellChildren child;
+	FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	guint i, j;
+	
+	j = ftt_cell_children_direction (n.c[d], od, &child);
+	for (i = 0; i < j; i++)
+	  if (child.c[i] && GFS_VARIABLE (child.c[i], v->i) == 0. &&
+	      (!GFS_IS_MIXED (child.c[i]) || GFS_STATE (child.c[i])->solid->s[od] > 0.))
+	    tag_cell (child.c[i], v, tag, size);
+      }
+    }
+}
+
+static void tag_new_region (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+
+  if (GFS_VARIABLE (cell, v->i) == 0.) {
+    GArray * sizes = data[1];
+    guint size = 0;
+
+    tag_cell (cell, v, sizes->len + 1, &size);
+    g_array_append_val (sizes, size);
+  }
+}
+
+static gboolean remove_small (FttCell * cell, gpointer * data)
+{
+  if (FTT_CELL_IS_LEAF (cell)) {
+    GArray * sizes = data[0];
+    GfsVariable * v = data[5];
+    guint * min = data[1], i = GFS_VARIABLE (cell, v->i) - 1.;
+
+    g_assert (GFS_VARIABLE (cell, v->i) > 0.);
+    if (g_array_index (sizes, guint, i) < *min) {
+      if (FTT_CELL_IS_ROOT (cell))
+	g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "root cell belongs to a pond");
+      else
+	ftt_cell_destroy (cell, data[2], data[3]);
+      return TRUE;
+    }
+    return FALSE;
+  }
+  else {
+    FttCellChildren child;
+    guint i;
+    gboolean changed = FALSE;
+
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i] && remove_small (child.c[i], data))
+	changed = TRUE;
+    if (FTT_CELL_IS_LEAF (cell)) {
+      /* all the children have been destroyed i.e. the cell belongs to a small pond */
+      if (FTT_CELL_IS_ROOT (cell))
+	g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "root cell belongs to a pond");
+      else
+	ftt_cell_destroy (cell, data[2], data[3]);
+    }
+    else if (changed)
+      gfs_cell_init_solid_fractions_from_children (cell);
+    return changed;
+  }
+}
+
+static void remove_small_box (GfsBox * box, gpointer * data)
+{
+  gboolean * changed = data[4];
+
+  if (remove_small (box->root, data))
+    *changed = TRUE;
+}
+
+/**
+ * gfs_domain_remove_ponds:
+ * @domain: a #GfsDomain.
+ * @min: the minimum size (in cells) of the ponds.
+ * @cleanup: a #FttCellCleanupFunc or %NULL.
+ * @data: user data to pass to @cleanup.
+ *
+ * Removes all the fluid "ponds" of @domain smaller than @min cells
+ * if @min is positive, or all the ponds but the - at min largest ones
+ * if @min is negative.
+ *
+ * If the domain is modified its boundaries are re"matched" using
+ * gfs_domain_match().
+ */
+void gfs_domain_remove_ponds (GfsDomain * domain, 
+			      gint min,
+			      FttCellCleanupFunc cleanup,
+			      gpointer data)
+{
+  GArray * sizes;
+  gpointer dat[6];
+  guint minsize;
+  gboolean changed = FALSE;
+  GfsVariable * v;
+
+  g_return_if_fail (domain != NULL);
+
+  v = gfs_temporary_variable (domain);
+  sizes = g_array_new (FALSE, FALSE, sizeof (guint));
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, v);
+  dat[0] = v;
+  dat[1] = sizes;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) tag_new_region, dat);
+  g_assert (sizes->len > 0);
+  if (min >= 0)
+    minsize = min;
+  else if (-min >= sizes->len)
+    minsize = 0;
+  else {
+    guint * tmp = g_malloc (sizes->len*sizeof (guint));
+    memcpy (tmp, sizes->data, sizes->len*sizeof (guint));
+    qsort (tmp, sizes->len, sizeof (guint), greater);
+    minsize = tmp[-1 - min];
+    g_free (tmp);
+  }
+  dat[0] = sizes;
+  dat[1] = &minsize;
+  dat[2] = cleanup;
+  dat[3] = data;
+  dat[4] = &changed;
+  dat[5] = v;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) remove_small_box, dat);
+  g_array_free (sizes, TRUE);
+  gts_object_destroy (GTS_OBJECT (v));
+  if (changed)
+    gfs_domain_match (domain);
+}
+
+static gboolean tag_speck (FttCell * cell, GfsVariable * v)
+{
+  if (GFS_VARIABLE (cell, v->i) == 0.) {
+    FttDirection d;
+    FttCellNeighbors n;
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+    
+    g_assert (FTT_CELL_IS_LEAF (cell));
+    ftt_cell_neighbors (cell, &n);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (!n.c[d])
+	return FALSE;
+    GFS_VARIABLE (cell, v->i) = 1.;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (GFS_VARIABLE (n.c[d], v->i) == 0. && 
+	  !GFS_CELL_IS_BOUNDARY (n.c[d]) &&
+	  solid->s[d] > 0. && solid->s[d] < 1.) {
+	g_assert (GFS_IS_MIXED (n.c[d]));
+	if (FTT_CELL_IS_LEAF (n.c[d])) {
+	  if (!tag_speck (n.c[d], v)) {
+	    GFS_VARIABLE (cell, v->i) = 0.;
+	    return FALSE;
+	  }
+	}
+	else {
+	  FttCellChildren child;
+	  FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	  guint i;
+	  
+#if FTT_2D3
+	  g_assert_not_implemented ();
+#endif	
+	  ftt_cell_children_direction (n.c[d], od, &child);
+	  for (i = 0; i < FTT_CELLS/2; i++)
+	    if (!child.c[i] || (GFS_VARIABLE (child.c[i], v->i) == 0 && 
+				GFS_IS_MIXED (child.c[i]) &&
+				!tag_speck (child.c[i], v))) {
+	      GFS_VARIABLE (cell, v->i) = 0.;
+	      return FALSE;
+	    }
+	}
+      }
+  }
+  return TRUE;
+}
+
+static void fill_speck (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+
+  if (GFS_VARIABLE (cell, v->i) == 1.) {
+    gboolean * changed = data[1];
+    g_free (GFS_STATE (cell)->solid);
+    GFS_STATE (cell)->solid = NULL;
+    *changed = TRUE;
+  }
+}
+
+/**
+ * gfs_domain_remove_specks:
+ * @domain: a #GfsDomain.
+ *
+ * Removes all the solid "specks" of @domain. Solid specks are islands
+ * which do not contain any empty cell.
+ *
+ * Note that the domain's boundaries are not "matched" automatically.
+ */
+void gfs_domain_remove_specks (GfsDomain * domain)
+{
+  gboolean changed = FALSE;
+  GfsVariable * v;
+  gpointer data[2];
+
+  g_return_if_fail (domain != NULL);
+
+  v = gfs_temporary_variable (domain);
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL,
+			     (FttCellTraverseFunc) gfs_cell_reset, v);
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseFunc) tag_speck, v);
+  data[0] = v;
+  data[1] = &changed;
+  gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseFunc) fill_speck, data);
+  gts_object_destroy (GTS_OBJECT (v));
+  if (changed)
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_init_solid_fractions_from_children, 
+			      NULL);
+    
+}
+
+/**
+ * gfs_domain_timer_start:
+ * @domain: a #GfsDomain.
+ * @name: the name of the timer.
+ *
+ * Starts timer @name of @domain. If @name does not exist it is
+ * created first.
+ */
+void gfs_domain_timer_start (GfsDomain * domain, const gchar * name)
+{
+  GfsTimer * t;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (name != NULL);
+
+  t = g_hash_table_lookup (domain->timers, name);
+  if (t == NULL) {
+    t = g_malloc (sizeof (GfsTimer));
+    gts_range_init (&t->r);
+    g_hash_table_insert (domain->timers, g_strdup (name), t);
+  }
+  else
+    g_return_if_fail (t->start < 0.);
+  t->start = gfs_clock_elapsed (domain->timer);
+}
+
+/**
+ * gfs_domain_timer_stop:
+ * @domain: a #GfsDomain.
+ * @name: the name of the timer.
+ *
+ * Stops timer @name of @domain. This function fails if @name is not a
+ * timer of @domain.
+ */
+void gfs_domain_timer_stop (GfsDomain * domain, const gchar * name)
+{
+  GfsTimer * t;
+  gdouble end;
+
+  g_return_if_fail (domain != NULL);
+  end = gfs_clock_elapsed (domain->timer);
+  g_return_if_fail (name != NULL);
+
+  t = g_hash_table_lookup (domain->timers, name);
+  g_return_if_fail (t != NULL);
+  g_return_if_fail (t->start >= 0.);
+
+  gts_range_add_value (&t->r, end - t->start);
+  gts_range_update (&t->r);
+  t->start = -1.;
+}
+
+static void cell_combine_traverse (FttCell * cell,
+				   FttCell * parent,
+				   FttCellCombineTraverseFunc inside,
+				   gpointer idata,
+				   FttCellTraverseFunc outside,
+				   gpointer odata)
+{
+  FttCell * locate;
+  FttVector p;
+
+  ftt_cell_pos (cell, &p);
+  locate = ftt_cell_locate (parent, p, ftt_cell_level (cell));
+  if (locate == NULL) {
+    if (outside)
+      ftt_cell_traverse (cell, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, outside, odata);
+  }
+  else {
+    if (FTT_CELL_IS_LEAF (cell))
+      (* inside) (cell, locate, idata);
+    else {
+      FttCellChildren child;
+      guint i;
+
+      ftt_cell_children (cell, &child);
+      for (i = 0; i < FTT_CELLS; i++)
+	if (child.c[i])
+	  cell_combine_traverse (child.c[i], locate, inside, idata, outside, odata);
+    }
+  }  
+}
+
+static void box_combine_traverse (GfsBox * box, gpointer * data)
+{
+  FttVector p;
+  FttCell * locate;
+
+  ftt_cell_pos (box->root, &p);
+  locate = gfs_domain_locate (data[0], p, ftt_cell_level (box->root), NULL);
+  if (locate == NULL) {
+    if (data[3])
+      ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, data[3], data[4]);
+  }
+  else
+    cell_combine_traverse (box->root, locate, data[1], data[2], data[3], data[4]);
+}
+
+/**
+ * gfs_domain_combine_traverse:
+ * @domain1: a #GfsDomain.
+ * @domain2: another #GfsDomain.
+ * @inside: function to call for each pair of cells.
+ * @idata: user data to pass to @inside.
+ * @outside: function to call for cells falling outside of @domain2 or
+ * %NULL.
+ * @odata: user data to pass to @outside.
+ *
+ * Calls @inside for each leaf cell of @domain1 contained in
+ * @domain2. The second cell argument to @inside is set to the cell of
+ * @domain2 containing the first cell argument.
+ *
+ * If @outside is not %NULL it is called for each leaf cell of
+ * @domain1 which is outside of @domain2.
+ */
+void gfs_domain_combine_traverse (GfsDomain * domain1,
+				  GfsDomain * domain2,
+				  FttCellCombineTraverseFunc inside,
+				  gpointer idata,
+				  FttCellTraverseFunc outside,
+				  gpointer odata)				  
+{
+  gpointer data[5];
+
+  g_return_if_fail (domain1 != NULL);
+  g_return_if_fail (domain2 != NULL);
+  g_return_if_fail (inside != NULL);
+
+  data[0] = domain2;
+  data[1] = inside;
+  data[2] = idata;
+  data[3] = outside;
+  data[4] = odata;
+
+  gts_container_foreach (GTS_CONTAINER (domain1), (GtsFunc) box_combine_traverse, data);
+}
+
+/**
+ * gfs_domain_add_derived_variable:
+ * @domain: a #GfsDomain.
+ * @info: the #GfsDerivedVariableInfo.
+ *
+ * Adds a derived variable described by @info to @domain.
+ *
+ * Returns: the #GfsDerivedVariable if the variable was successfully
+ * added to @domain or %NULL if a variable with the same name already
+ * exists.
+ */
+GfsDerivedVariable * gfs_domain_add_derived_variable (GfsDomain * domain, 
+						      GfsDerivedVariableInfo info)
+{
+  GfsDerivedVariable * v;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+
+  if (gfs_variable_from_name (domain->variables, info.name) ||
+      gfs_derived_variable_from_name (domain->derived_variables, info.name))
+    return NULL;
+  v = GFS_DERIVED_VARIABLE (gts_object_new (GTS_OBJECT_CLASS (gfs_derived_variable_class ())));
+  v->name = g_strdup (info.name);
+  v->description = info.description ? g_strdup (info.description) : NULL;
+  v->func = info.func;
+  v->data = info.data;
+  domain->derived_variables = g_slist_prepend (domain->derived_variables, v);
+  GTS_OBJECT (v)->reserved = domain;
+  return v;
+}
+
+/**
+ * gfs_domain_remove_derived_variable:
+ * @domain: a #GfsDomain.
+ * @name: the name of a #GfsDerivedVariable.
+ *
+ * Removes derived variable @name from @domain.
+ *
+ * Returns: %TRUE if the variable was successfully removed from @domain or
+ * %FALSE if a derived variable with the this name does not exist.
+ */
+gboolean gfs_domain_remove_derived_variable (GfsDomain * domain, const gchar * name)
+{
+  GSList * i;
+  
+  g_return_val_if_fail (domain != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+
+  i = domain->derived_variables;
+  while (i) {
+    GfsDerivedVariable * u = i->data;
+
+    if (!strcmp (u->name, name)) {
+      gts_object_destroy (GTS_OBJECT (u));
+      domain->derived_variables = g_slist_remove_link (domain->derived_variables, i);
+      g_slist_free (i);
+      return TRUE;
+    }
+    i = i->next;
+  }
+  return FALSE;
+}
+
+typedef struct {
+  FttDirection d;
+  GfsFunction * f;
+  GfsVariable * v;
+} SumData;
+
+static gdouble product (FttCell * cell, GfsFunction * f)
+{
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+  return ftt_cell_volume (cell)*(solid ? solid->a : 1.)*gfs_function_value (f, cell);
+}
+
+static void sum (FttCell * cell, SumData * data)
+{
+  FttCell * n = ftt_cell_neighbor (cell, data->d);
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+  if (!n || GFS_CELL_IS_BOUNDARY (n) || (solid && solid->s[data->d] == 0.)) {
+    gdouble s = 0.;
+
+    n = cell;
+    do {
+      /* fixme: does not work if the resolution varies along data->d */
+      g_assert (ftt_cell_level (n) == ftt_cell_level (cell));
+      s += product (n, data->f);
+      GFS_VARIABLE (n, data->v->i) = s;
+      n = ftt_cell_neighbor (n, FTT_OPPOSITE_DIRECTION (data->d));
+    } while (n && !GFS_CELL_IS_BOUNDARY (n) && 
+	     (!GFS_IS_MIXED (n) || GFS_STATE (n)->solid->s[data->d] > 0.));
+  }
+}
+
+/**
+ * gfs_domain_sum:
+ * @domain: a #GfsDomain.
+ * @d: the #FttDirection.
+ * @f: a #GfsFunction.
+ * @v: a #GfsVariable.
+ *
+ * Fills variable @v of each cell of @domain with the sum in direction
+ * @d of the volume-weighted function @f.
+ */
+void gfs_domain_sum (GfsDomain * domain, FttDirection d, GfsFunction * f, GfsVariable * v)
+{
+  SumData data;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (d >= 0 && d < FTT_NEIGHBORS);
+  g_return_if_fail (f != NULL);
+  g_return_if_fail (v != NULL);
+
+  data.d = d;
+  data.f = f;
+  data.v = v;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) sum, &data);
+}
+
+static void filter (FttCell * cell, gpointer * data)
+{
+  FttDirection d[4*(FTT_DIMENSION - 1)][FTT_DIMENSION] = {
+#if FTT_2D
+    {FTT_RIGHT, FTT_TOP}, {FTT_RIGHT, FTT_BOTTOM}, {FTT_LEFT, FTT_TOP}, {FTT_LEFT, FTT_BOTTOM}
+#else
+    {FTT_RIGHT, FTT_TOP, FTT_FRONT}, {FTT_RIGHT, FTT_BOTTOM, FTT_FRONT}, 
+    {FTT_LEFT, FTT_TOP, FTT_FRONT}, {FTT_LEFT, FTT_BOTTOM, FTT_FRONT},
+    {FTT_RIGHT, FTT_TOP, FTT_BACK}, {FTT_RIGHT, FTT_BOTTOM, FTT_BACK}, 
+    {FTT_LEFT, FTT_TOP, FTT_BACK}, {FTT_LEFT, FTT_BOTTOM, FTT_BACK}
+#endif
+  };
+  guint i;
+  gdouble val = 0.;
+  GfsVariable * a = data[0];
+  GfsVariable * b = data[1];
+
+  for (i = 0; i < 4*(FTT_DIMENSION - 1); i++)
+    val += gfs_cell_corner_value (cell, d[i], a, -1);
+  GFS_VARIABLE (cell, b->i) = val/(4*(FTT_DIMENSION - 1));
+}
+
+/**
+ * gfs_domain_filter:
+ * @domain: a #GfsDomain.
+ * @v: a #GfsVariable.
+ * @fv: the filtered variable or %NULL.
+ *
+ * Apply a "corner-averaging" filter to variable @v on all leaf cells
+ * of @domain.
+ *
+ * If @fv is %NULL, @v is replaced by its filtered value.
+ */
+void gfs_domain_filter (GfsDomain * domain, GfsVariable * v, GfsVariable * fv)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+
+  gpointer data[2];
+  data[0] = v;
+  data[1] = fv ? fv : gfs_temporary_variable (domain);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) filter, data);
+  if (fv == NULL) {
+    gfs_variables_swap (data[0], data[1]);
+    gts_object_destroy (data[1]);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v);
+  }
+  else
+    gfs_domain_copy_bc (domain, FTT_TRAVERSE_LEAFS, -1, v, fv);
+}
+
+struct _GfsRequest {  
+  FILE * fp;
+  long length;
+#ifdef HAVE_MPI
+  MPI_Request request[2];
+  void * buf;
+#endif
+};
+
+/**
+ * gfs_send_objects:
+ * @list: a list of #GtsObject.
+ * @dest: the rank of the destination PE.
+ *
+ * Sends the objects in @list to PE @dest of a parallel simulation.
+ * This is a non-blocking operation which returns a handler which must
+ * be cleared by calling gfs_wait().
+ *
+ * Note that this functions assumes that the write() method of the
+ * #GtsObject sent begins by writing the object class name.
+ *
+ * Returns: a #GfsRequest.
+ */
+GfsRequest * gfs_send_objects (GSList * list, int dest)
+{
+#ifdef HAVE_MPI
+  GfsRequest * r = g_malloc (sizeof (GfsRequest));
+  r->fp = tmpfile ();
+  int fd = fileno (r->fp);
+  struct stat sb;
+  while (list) {
+    GtsObject * object = list->data;
+    g_assert (object->klass->write != NULL);
+    (* object->klass->write) (object, r->fp);
+    fputc ('\n', r->fp);
+    list = list->next;
+  }
+  fflush (r->fp);
+  g_assert (fstat (fd, &sb) != -1);
+  r->length = sb.st_size;
+  MPI_Isend (&r->length, 1, MPI_LONG, dest, 0, MPI_COMM_WORLD, &r->request[0]);
+  /*  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "sending %ld bytes to PE %d", length, dest); */
+  if (r->length > 0) {
+    r->buf = mmap (NULL, r->length, PROT_READ, MAP_PRIVATE, fd, 0);
+    g_assert (r->buf != MAP_FAILED);
+    MPI_Isend (r->buf, r->length, MPI_BYTE, dest, 1, MPI_COMM_WORLD, &r->request[1]);
+  }
+  return r;
+#else  /* not HAVE_MPI */
+  return NULL;
+#endif /* HAVE_MPI */
+}
+
+/**
+ * gfs_wait:
+ * @r: a #GfsRequest.
+ *
+ * Waits for completion of and deallocates @r.
+ */
+void gfs_wait (GfsRequest * r)
+{
+#ifdef HAVE_MPI
+  g_return_if_fail (r != NULL);
+
+  MPI_Status status;
+  MPI_Wait (&r->request[0], &status);
+  if (r->length > 0) {
+    MPI_Wait (&r->request[1], &status);
+    munmap (r->buf, r->length);
+  }
+  fclose (r->fp);
+  g_free (r);
+#endif /* HAVE_MPI */
+}
+
+/**
+ * gfs_receive_objects:
+ * @domain: a #GfsDomain.
+ * @src: the rank of the source PE.
+ *
+ * Receives a list of #GtsObject from PE @src of a parallel simulation.
+ *
+ * Returns: a list of newly-allocated objects.
+ */
+GSList * gfs_receive_objects (GfsDomain * domain, int src)
+{
+  g_return_val_if_fail (domain != NULL, NULL);
+
+#ifdef HAVE_MPI
+  MPI_Status status;
+  long length;
+  MPI_Recv (&length, 1, MPI_LONG, src, 0, MPI_COMM_WORLD, &status);
+  /*  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "receiving %ld bytes from PE %d", length, src); */
+  if (length > 0) {
+    char * buf = g_malloc (length);
+    MPI_Recv (buf, length, MPI_BYTE, src, 1, MPI_COMM_WORLD, &status);
+    FILE * f = tmpfile ();
+    fwrite (buf, 1, length, f);
+    rewind (f);
+    GtsFile * fp = gts_file_new (f);
+    GSList * list = NULL;
+    while (fp->type == GTS_STRING) {
+      GtsObjectClass * klass = gfs_object_class_from_name (fp->token->str);
+      if (klass == NULL)
+	g_error ("gfs_receive_object():%d:%d: unknown class '%s'", 
+		 fp->line, fp->pos, fp->token->str);
+      GtsObject * object = gts_object_new (klass);
+      gfs_object_simulation_set (object, domain);
+      g_assert (klass->read);
+      (* klass->read) (&object, fp);
+      if (fp->type == GTS_ERROR)
+	g_error ("gfs_receive_object():%d:%d: %s", fp->line, fp->pos, fp->error);
+      list = g_slist_prepend (list, object);
+      while (fp->type == '\n')
+	gts_file_next_token (fp);
+    }
+    gts_file_destroy (fp);
+    fclose (f);
+    g_free (buf);
+    return list;
+  }
+#endif /* HAVE_MPI */
+  return NULL;
+}
+
+static void unlink_box (GfsBox * box, gint * dest)
+{
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOX (box->neighbor[d])) {
+      GfsBox * nbox = GFS_BOX (box->neighbor[d]);
+      FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+      nbox->neighbor[od] = NULL;
+      gfs_boundary_mpi_new (gfs_boundary_mpi_class (), nbox, od, *dest, box->id);
+      box->neighbor[d] = NULL;
+      gfs_boundary_mpi_new (gfs_boundary_mpi_class (), box, d, nbox->pid, nbox->id);
+    }
+}
+
+static void setup_binary_IO (GfsDomain * domain)
+{
+  /* make sure that all the variables are sent */
+  g_slist_free (domain->variables_io);
+  domain->variables_io = NULL;
+  GSList * i = domain->variables;
+  while (i) {
+    if (GFS_VARIABLE1 (i->data)->name)
+      domain->variables_io = g_slist_append (domain->variables_io, i->data);
+    i = i->next;
+  }
+  domain->binary = TRUE;	
+}
+
+/**
+ * gfs_send_boxes:
+ * @domain: a #GfsDomain.
+ * @boxes: a list of #GfsBox belonging to @domain.
+ * @dest: the destination processor id.
+ *
+ * Send boxes to @dest and removes them from @domain.
+ * This is a non-blocking operation.
+ *
+ * Returns: a #GfsRequest which must be cleared using gfs_wait().
+ */
+GfsRequest * gfs_send_boxes (GfsDomain * domain, GSList * boxes, int dest)
+{
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (dest != domain->pid, NULL);
+
+  g_slist_foreach (boxes, (GFunc) unlink_box, &dest);
+  setup_binary_IO (domain);
+  GfsRequest * r = gfs_send_objects (boxes, dest);
+  g_slist_foreach (boxes, (GFunc) gts_object_destroy, NULL);
+  locate_array_destroy (domain->array);
+  domain->array = locate_array_new (domain);
+  return r;
+}
+
+/**
+ * gfs_receive_boxes:
+ * @domain: a #GfsDomain.
+ * @src: the source processor id.
+ *
+ * Receive boxes from @src and adds them to @domain.
+ *
+ * Returns: the list of boxes received.
+ */
+GSList * gfs_receive_boxes (GfsDomain * domain, int src)
+{
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (src != domain->pid, NULL);
+
+  setup_binary_IO (domain);
+  GSList * boxes = gfs_receive_objects (domain, src);
+  if (boxes) {
+    /* Create array for fast linking of ids to GfsBox pointers */
+    GPtrArray * ids = box_ids (domain);
+	  
+    /* Convert internal GfsBoundaryMpi into graph edges */
+    g_slist_foreach (boxes, (GFunc) convert_boundary_mpi_into_edges, ids);
+    g_ptr_array_free (ids, TRUE);
+
+    /* Update LocateArray */
+    locate_array_destroy (domain->array);
+    domain->array = locate_array_new (domain);
+  }
+  return boxes;
+}
diff --git a/src/domain.h b/src/domain.h
new file mode 100644
index 0000000..1133baf
--- /dev/null
+++ b/src/domain.h
@@ -0,0 +1,429 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __DOMAIN_H__
+#define __DOMAIN_H__
+
+#include "boundary.h"
+#include "surface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GfsDomainClass     GfsDomainClass;
+typedef struct _GfsSourceDiffusion GfsSourceDiffusion;
+typedef struct _GfsTimer           GfsTimer;
+
+struct _GfsTimer {
+  GtsRange r;
+  gdouble start;
+};
+
+struct _GfsDomain {
+  GtsWGraph parent;
+
+  int pid;
+  GfsClock * timer;
+  GHashTable * timers;
+
+  GtsRange timestep;
+  GtsRange size;
+
+  gboolean profile_bc;
+
+  GtsRange mpi_messages;
+  GtsRange mpi_wait;
+
+  guint rootlevel;
+  FttVector refpos;
+  FttVector lambda;
+
+  GArray * allocated;
+  GSList * variables;
+  GSList * derived_variables;
+
+  GfsVariable * velocity[FTT_DIMENSION];
+
+  GSList * variables_io;
+  gboolean binary;
+  gint max_depth_write;
+
+  FttCellInitFunc cell_init;
+  gpointer cell_init_data;
+
+  gint version;
+
+  gpointer array;
+
+  gboolean overlap; /* whether to overlap MPI communications with computation */
+
+  /* coordinate metrics */
+  gpointer metric_data;
+  gdouble (* face_metric)  (const GfsDomain *, const FttCellFace *);
+  gdouble (* cell_metric)  (const GfsDomain *, const FttCell *);
+  gdouble (* solid_metric) (const GfsDomain *, const FttCell *);
+  gdouble (* scale_metric) (const GfsDomain *, const FttCell *, FttComponent);
+};
+
+struct _GfsDomainClass {
+  GtsWGraphClass parent_class;
+
+  void    (* post_read) (GfsDomain *, GtsFile * fp);
+};
+
+#define GFS_DOMAIN(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsDomain,\
+					           gfs_domain_class ())
+#define GFS_DOMAIN_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsDomainClass,\
+						   gfs_domain_class())
+#define GFS_IS_DOMAIN(obj)         (gts_object_is_from_class (obj,\
+						   gfs_domain_class ()))
+
+#define gfs_domain_variables_number(d) ((d)->allocated->len - 1)
+#define gfs_domain_variables_size(d)   (sizeof (GfsStateVector) +\
+                                        sizeof (gdouble)*((d)->allocated->len - 1))
+     
+GfsDomainClass * gfs_domain_class          (void);
+void         gfs_domain_cell_traverse         (GfsDomain * domain,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data);
+#define gfs_domain_traverse_leaves(d,f,data)  (gfs_domain_cell_traverse(d, \
+					    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, f,data))
+void         gfs_domain_cell_traverse_condition (GfsDomain * domain,
+						 FttTraverseType order,
+						 FttTraverseFlags flags,
+						 gint max_depth,
+						 FttCellTraverseFunc func,
+						 gpointer data,
+						 gboolean (* condition) (FttCell *, gpointer),
+						 gpointer cdata);
+void         gfs_domain_cell_traverse_box     (GfsDomain * domain,
+					       GtsBBox * box,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data);
+void         gfs_domain_cell_traverse_boundary (GfsDomain * domain,
+					       FttDirection d,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data);
+void         gfs_domain_traverse_mixed        (GfsDomain * domain,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       FttCellTraverseFunc func,
+					       gpointer data);
+void         gfs_domain_traverse_cut          (GfsDomain * domain,
+					       GfsGenericSurface * s,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       FttCellTraverseCutFunc func,
+					       gpointer data);
+void         gfs_domain_traverse_cut_2D       (GfsDomain * domain,
+					       GfsGenericSurface * s,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       FttCellTraverseCutFunc func,
+					       gpointer data);
+void         gfs_domain_face_traverse         (GfsDomain * domain,
+					       FttComponent c,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttFaceTraverseFunc func,
+					       gpointer data);
+void         gfs_domain_bc                    (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       GfsVariable * v);
+void         gfs_domain_copy_bc               (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       GfsVariable * v,
+					       GfsVariable * v1);
+void         gfs_domain_homogeneous_bc        (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       GfsVariable * ov,
+					       GfsVariable * v);
+void         gfs_traverse_and_homogeneous_bc  (GfsDomain * domain,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data,
+					       GfsVariable * ov,
+					       GfsVariable * v);
+void         gfs_traverse_and_bc              (GfsDomain * domain,
+					       FttTraverseType order,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data,
+					       GfsVariable * v,
+					       GfsVariable * v1);
+void         gfs_domain_face_bc               (GfsDomain * domain,
+					       FttComponent c,
+					       GfsVariable * v);
+void         gfs_domain_match                 (GfsDomain * domain);
+void         gfs_domain_surface_bc            (GfsDomain * domain,
+					       GfsVariable * v);
+guint        gfs_domain_depth                 (GfsDomain * domain);
+GtsRange     gfs_domain_stats_variable        (GfsDomain * domain,
+					       GfsVariable * v,
+					       FttTraverseFlags flags,
+					       gint max_depth);
+GtsRange     gfs_domain_stats_solid           (GfsDomain * domain);
+void         gfs_domain_stats_merged          (GfsDomain * domain,
+					       GtsRange * solid,
+					       GtsRange * number);
+void         gfs_domain_stats_balance         (GfsDomain * domain,
+					       GtsRange * size,
+					       GtsRange * boundary,
+					       GtsRange * mpiwait);
+GfsNorm      gfs_domain_norm_variable         (GfsDomain * domain,
+					       GfsVariable * v,
+					       GfsFunction * w,
+					       FttTraverseFlags flags,
+					       gint max_depth);
+GfsNorm      gfs_domain_norm_residual         (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth,
+					       gdouble dt,
+					       GfsVariable * res);
+GfsVariable ** gfs_domain_velocity            (GfsDomain * domain);
+GfsNorm      gfs_domain_norm_velocity         (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth);
+GfsDomain *  gfs_domain_read                  (GtsFile * fp);
+void         gfs_domain_split                 (GfsDomain * domain,
+					       gboolean one_box_per_pe);
+FttCell *    gfs_domain_locate                (GfsDomain * domain,
+					       FttVector target,
+					       gint max_depth,
+					       GfsBox ** where);
+FttCell *    gfs_domain_boundary_locate       (GfsDomain * domain,
+					       FttVector target,
+					       gint max_depth,
+					       GtsObject ** where);
+gdouble      gfs_domain_cell_point_distance2  (GfsDomain * domain,
+					       GtsPoint * p,
+					       gdouble (* distance2) (FttCell *, 
+								      GtsPoint *, 
+								      gpointer),
+					       gpointer data,
+					       FttCell ** closest);
+void         gfs_domain_advect_point          (GfsDomain * domain, 
+					       FttVector * p,
+					       gdouble dt);
+guint        gfs_domain_size                  (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth);
+gdouble      gfs_domain_cfl                   (GfsDomain * domain,
+					       FttTraverseFlags flags,
+					       gint max_depth);
+void         gfs_cell_init                    (FttCell * cell,
+					       GfsDomain * domain);
+void         gfs_cell_reinit                  (FttCell * cell, 
+					       GfsDomain * domain);
+void         gfs_cell_fine_init               (FttCell * cell,
+					       GfsDomain * domain);
+void         gfs_cell_copy                    (const FttCell * from, 
+					       FttCell * to,
+					       GfsDomain * domain);
+void         gfs_cell_read                    (FttCell * cell, 
+					       GtsFile * fp,
+					       GfsDomain * domain);
+void         gfs_cell_write                   (const FttCell * cell, 
+					       FILE * fp,
+					       GSList * variables);
+void         gfs_cell_read_binary             (FttCell * cell, 
+					       GtsFile * fp,
+					       GfsDomain * domain);
+void         gfs_cell_write_binary            (const FttCell * cell, 
+					       FILE * fp,
+					       GSList * variables);
+guint        gfs_domain_alloc                 (GfsDomain * domain);
+void         gfs_domain_free                  (GfsDomain * domain, 
+					       guint i);
+GfsVariable * gfs_domain_add_variable         (GfsDomain * domain, 
+					       const gchar * name,
+					       const gchar * description);
+GfsVariable * gfs_domain_get_or_add_variable  (GfsDomain * domain,
+					       const gchar * name,
+					       const gchar * description);
+void         gfs_domain_solid_force           (GfsDomain * domain, 
+					       FttVector * pf,
+					       FttVector * vf,
+					       FttVector * pm,
+					       FttVector * vm,
+					       GfsFunction * weight);
+guint        gfs_domain_tag_droplets          (GfsDomain * domain,
+					       GfsVariable * c,
+					       GfsVariable * tag);
+void         gfs_domain_remove_droplets       (GfsDomain * domain,
+					       GfsVariable * c,
+					       GfsVariable * v,
+					       gint min);
+void         gfs_domain_remove_ponds          (GfsDomain * domain, 
+					       gint min,
+					       FttCellCleanupFunc cleanup,
+					       gpointer data);
+void         gfs_domain_remove_specks         (GfsDomain * domain);
+void         gfs_domain_timer_start           (GfsDomain * domain, 
+					       const gchar * name);
+void         gfs_domain_timer_stop            (GfsDomain * domain, 
+					       const gchar * name);
+typedef
+void      (* FttCellCombineTraverseFunc)      (FttCell * cell1, 
+					       FttCell * cell2, 
+					       gpointer data);
+void         gfs_domain_combine_traverse      (GfsDomain * domain1,
+					       GfsDomain * domain2,
+					       FttCellCombineTraverseFunc inside,
+					       gpointer idata,
+					       FttCellTraverseFunc outside,
+					       gpointer odata);
+
+typedef struct {
+  gchar * name, * description;
+  gpointer func, data;
+} GfsDerivedVariableInfo;
+
+GfsDerivedVariable * gfs_domain_add_derived_variable  (GfsDomain * domain, 
+						       GfsDerivedVariableInfo info);
+gboolean     gfs_domain_remove_derived_variable (GfsDomain * domain, 
+						 const gchar * name);
+void         gfs_domain_sum                     (GfsDomain * domain, 
+						 FttDirection d, 
+						 GfsFunction * f, 
+						 GfsVariable * v);
+void         gfs_domain_filter                  (GfsDomain * domain, 
+						 GfsVariable * v,
+						 GfsVariable * fv);
+typedef struct _GfsRequest GfsRequest;
+GfsRequest * gfs_send_objects                   (GSList * list,
+						 int dest);
+void         gfs_wait                           (GfsRequest * r);
+GSList *     gfs_receive_objects                (GfsDomain * domain, 
+						 int src);
+GfsRequest * gfs_send_boxes                     (GfsDomain * domain, 
+						 GSList * boxes, 
+						 int dest);
+GSList *     gfs_receive_boxes                  (GfsDomain * domain, 
+						 int src);
+
+/**
+ * gfs_domain_face_fraction:
+ * @domain; a #GfsDomain.
+ * @face: a #FttCellFace.
+ *
+ * Returns: the surface fraction of @face taking into account any
+ * orthogonal metric of @domain.
+ */
+static inline
+gdouble gfs_domain_face_fraction (const GfsDomain * domain, const FttCellFace * face)
+{
+  gdouble f = GFS_FACE_FRACTION (face);
+  if (domain->face_metric)
+    f *= (* domain->face_metric) (domain, face);
+  return f;
+}
+
+/**
+ * gfs_domain_face_fraction_right:
+ * @domain; a #GfsDomain.
+ * @face: a #FttCellFace.
+ *
+ * Returns: the surface fraction "to the right" of @face taking into account any
+ * orthogonal metric of @domain.
+ */
+static inline
+gdouble gfs_domain_face_fraction_right (const GfsDomain * domain, const FttCellFace * face)
+{
+  gdouble f = GFS_FACE_FRACTION_RIGHT (face);
+  if (domain->face_metric) {
+    FttCellFace face1;
+    face1.cell = face->neighbor;
+    face1.d = FTT_OPPOSITE_DIRECTION (face->d);
+    f *= (* domain->face_metric) (domain, &face1);
+  }
+  return f;
+}
+
+/**
+ * gfs_domain_cell_fraction:
+ * @domain; a #GfsDomain.
+ * @cell: a #FttCell.
+ *
+ * Returns: the volume fraction of @cell taking into account any
+ * orthogonal metric of @domain.
+ */
+static inline
+gdouble gfs_domain_cell_fraction (const GfsDomain * domain, const FttCell * cell)
+{
+  gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+  if (domain->cell_metric)
+    a *= (* domain->cell_metric) (domain, cell);
+  return a;
+}
+
+/**
+ * gfs_domain_solid_metric:
+ * @domain; a #GfsDomain.
+ * @cell: a mixed #FttCell.
+ *
+ * Returns: the coordinate metric at the center of area of the solid
+ * surface contained within @cell.
+ */
+static inline
+gdouble gfs_domain_solid_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  if (domain->solid_metric)
+    return (* domain->solid_metric) (domain, cell);
+  return 1.;
+}
+
+/**
+ * gfs_cell_volume:
+ * @cell: a #FttCell.
+ * @domain: a #GfsDomain.
+ *
+ * Returns: the volume of @cell.
+ */
+static inline
+gdouble gfs_cell_volume (const FttCell * cell, const GfsDomain * domain)
+{
+  double v = ftt_cell_volume (cell)*(GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.);
+  return domain->cell_metric ? (* domain->cell_metric) (domain, cell)*v : v;
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __DOMAIN_H__ */
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..2d51cef
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,2223 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <math.h>
+#include "event.h"
+#include "solid.h"
+#include "output.h"
+
+/**
+ * gfs_event_next:
+ * @event: a #GfsEvent.
+ * @sim: a #GfsSimulation.
+ *
+ * Returns: the next physical time at which @event will be realised.
+ */
+gdouble gfs_event_next (GfsEvent * event, GfsSimulation * sim)
+{
+  g_return_val_if_fail (event != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (sim != NULL, G_MAXDOUBLE);
+
+  if (sim->time.t < event->t)
+    return event->t;
+  if (event->t >= event->end ||
+      event->i >= event->iend ||
+      sim->time.t > event->end || 
+      sim->time.i > event->iend)
+    return G_MAXDOUBLE;
+  if (event->end_event)
+    return G_MAXDOUBLE;
+  if (sim->time.t >= event->t) {
+    if (event->istep < G_MAXINT) {
+      if (event->n == 0)
+	return G_MAXDOUBLE;
+    }
+    else
+      return event->start + (event->n + 1)*event->step;
+  }
+  if (sim->time.i >= event->i && event->step < G_MAXDOUBLE && event->n == 0)
+    return sim->time.t + event->step;
+  return G_MAXDOUBLE;
+}
+
+static gboolean gfs_event_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if (event->redo) {
+    event->redo = FALSE;
+    return event->realised;
+  }
+  if (event->t >= event->end ||
+      event->i >= event->iend ||
+      sim->time.t > event->end || 
+      sim->time.i > event->iend) {
+    gts_object_destroy (GTS_OBJECT (event));
+    return FALSE;
+  }
+  if (event->end_event) {
+    if (event->n == 0 &&
+	(sim->time.t >= sim->time.end ||
+	 sim->time.i >= sim->time.iend)) {
+      event->n = 1;
+      return (event->realised = TRUE);
+    }
+    else
+      return (event->realised = FALSE);
+  }
+  if (sim->time.t >= event->t) {
+    if (event->istep < G_MAXINT) {
+      if (event->n == 0) {
+	event->i = sim->time.i + event->istep;
+	event->n++;
+	return (event->realised = TRUE);
+      }
+    }
+    else {
+      event->n++;
+      event->t = event->start + event->n*event->step;
+      return (event->realised = TRUE);
+    }
+  }
+  if (sim->time.i >= event->i) {
+    if (event->step < G_MAXDOUBLE) {
+      if (event->n == 0) {
+	event->start = sim->time.t;
+	event->t = event->start + event->step;
+	event->n = 1;
+	return (event->realised = TRUE);
+      }
+    }
+    else {
+      event->n++;
+      event->i += event->istep;
+      return (event->realised = TRUE);
+    }
+  }
+  return (event->realised = FALSE);
+}
+
+static void gfs_event_write (GtsObject * object, FILE * fp)
+{
+  GfsEvent * event = GFS_EVENT (object);
+
+  fprintf (fp, "%s { ", object->klass->info.name);
+  if (event->end_event)
+    fputs ("start = end ", fp);
+  else {
+    if (event->start > 0. && event->start < G_MAXDOUBLE/2.)
+      fprintf (fp, "start = %g ", event->start);
+    if (event->step < G_MAXDOUBLE)
+      fprintf (fp, "step = %g ", event->step);
+    if (event->end < G_MAXDOUBLE)
+      fprintf (fp, "end = %g ", event->end);
+    if (event->istart > 0 && event->istart < G_MAXINT/2)
+      fprintf (fp, "istart = %u ", event->istart);
+    if (event->istep < G_MAXINT)
+      fprintf (fp, "istep = %u ", event->istep);
+    if (event->iend < G_MAXINT)
+      fprintf (fp, "iend = %u ", event->iend);
+  }
+  fputc ('}', fp);
+}
+
+static void event_init (GfsEvent * object)
+{
+  object->t      = 0.;
+  object->start  = 0.;
+  object->end    = G_MAXDOUBLE;
+  object->step   = G_MAXDOUBLE;
+
+  object->i      = 0;
+  object->istart = 0;
+  object->iend   = G_MAXINT;
+  object->istep  = G_MAXINT;
+
+  object->n         = 0;
+  object->end_event = FALSE;
+}
+
+static void gfs_event_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEvent * event = GFS_EVENT (*o);
+  GtsObjectClass * klass;
+  gboolean class_changed = FALSE;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsEventClass)");
+    return;
+  }
+  klass = gfs_object_class_from_name (fp->token->str);
+  if (klass == NULL) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_event_class ())) {
+    gts_file_error (fp, "`%s' is not a GfsEvent", fp->token->str);
+    return;
+  }
+  if (klass != (*o)->klass) {
+    *o = gts_object_new (klass);
+    gts_object_destroy (GTS_OBJECT (event));
+    event = GFS_EVENT (*o);
+    class_changed = TRUE;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_STRING, "start",  TRUE},
+      {GTS_DOUBLE, "end",    TRUE},
+      {GTS_DOUBLE, "step",   TRUE},
+      {GTS_UINT,   "istart", TRUE},
+      {GTS_UINT,   "iend",   TRUE},
+      {GTS_UINT,   "istep",  TRUE},
+      {GTS_NONE}
+    };
+    gchar * start = NULL;
+
+    var[0].data = &start;
+    var[1].data = &event->end;
+    var[2].data = &event->step;
+
+    var[3].data = &event->istart;
+    var[4].data = &event->iend;
+    var[5].data = &event->istep;
+ 
+    gts_file_assign_variables (fp, var);
+
+    if (fp->type == GTS_ERROR)
+      return;
+
+    if (start) {
+      if (!strcmp (start, "end")) {
+	event->end_event = TRUE;
+	if (var[1].set)
+	  gts_file_variable_error (fp, var, "end", 
+				   "end cannot be set for an `end' event");
+	else if (var[2].set)
+	  gts_file_variable_error (fp, var, "step", 
+				   "step cannot be set for an `end' event");
+	else if (var[3].set)
+	  gts_file_variable_error (fp, var, "istart", 
+				   "istart cannot be set for an `end' event");
+	else if (var[4].set)
+	  gts_file_variable_error (fp, var, "iend", 
+				   "iend cannot be set for an `end' event");
+	else if (var[5].set)
+	  gts_file_variable_error (fp, var, "istep", 
+				   "istep cannot be set for an `end' event");
+      }
+      else
+	event->start = atof (start);
+      g_free (start);
+    }
+
+    if (fp->type == GTS_ERROR)
+      return;
+
+    if (var[2].set && var[5].set) {
+      gts_file_variable_error (fp, var, "istep", 
+			       "step and istep cannot be set simultaneously");
+      return;
+    }
+    if (var[2].set)
+      event->istep = G_MAXINT;
+
+    if (var[2].set && event->step <= 0.) {
+      gts_file_variable_error (fp, var, "step",
+			       "step `%g' must be strictly positive", 
+			       event->step);
+      return;
+    }
+    if (!var[2].set && !var[5].set && var[1].set) {
+      gts_file_error (fp, "expecting a number (step or istep)");
+      return;
+    }
+    if (var[1].set && event->end <= event->start) {
+      gts_file_variable_error (fp, var, "end",
+			       "end `%g' must be larger than start `%g'", 
+			       event->end, event->start);
+      return;
+    }
+    if (event->start < 0. && var[1].set) {
+      gts_file_variable_error (fp, var, "end",
+			       "end cannot be specified for an `init' event");
+      return;
+    }
+    if (event->start < 0. && var[2].set)
+      event->start = 0.;
+    if (var[0].set || !var[3].set)
+      event->t = event->start;
+    else
+      event->t = event->start = G_MAXDOUBLE/2.;
+
+    if (!var[5].set && !var[2].set && var[4].set) {
+      gts_file_error (fp, "expecting a number (istep or step)");
+      return;
+    }
+    if (var[3].set && event->iend <= event->istart) {
+      gts_file_variable_error (fp, var, "iend",
+			       "iend `%u' must be larger than istart `%u'", 
+			       event->iend, event->istart);
+      return;
+    }
+    if (var[3].set || !var[0].set)
+      event->i = event->istart;
+    else
+      event->i = event->istart = G_MAXINT/2;
+  }
+
+  if (class_changed && fp->type != '\n' && klass->read)
+    (* klass->read) (o, fp);
+}
+
+static void gfs_event_class_init (GfsEventClass * klass)
+{
+  klass->event = gfs_event_event;
+
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_write;
+  GTS_OBJECT_CLASS (klass)->read  = gfs_event_read;
+}
+
+GfsEventClass * gfs_event_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_info = {
+      "GfsEvent",
+      sizeof (GfsEvent),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_class_init,
+      (GtsObjectInitFunc) event_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
+			    &gfs_event_info);
+  }
+
+  return klass;
+}
+
+GfsEvent * gfs_event_new (GfsEventClass * klass)
+{
+  GfsEvent * object;
+
+  g_return_val_if_fail (klass != NULL, NULL);
+
+  object = GFS_EVENT (gts_object_new (GTS_OBJECT_CLASS (klass)));
+
+  return object;
+}
+
+/**
+ * gfs_event_set:
+ * @e: a #GfsEvent.
+ * @start: start time.
+ * @end: end time.
+ * @step: time step.
+ * @istart: start iteration.
+ * @iend: end iteration.
+ * @istep: iteration step.
+ *
+ * Sets the properties of event @e.
+ *
+ * If any of the arguments is negative, the corresponding value in @e
+ * is unchanged.
+ */
+void gfs_event_set (GfsEvent * e,
+		    gdouble start, gdouble end, gdouble step,
+		    gint istart, gint iend, gint istep)
+{
+  g_return_if_fail (e != NULL);
+  g_return_if_fail (end < 0. || start < 0. || start <= end);
+  g_return_if_fail (istep >= 0 || step >= 0. || iend < 0);
+  g_return_if_fail (istart < 0 || iend < 0 || istart <= iend);
+  
+  if (start >= 0.) e->start = start;
+  if (end >= 0.)   e->end = end;
+  if (step >= 0.)  e->step = step;
+  if (istart >= 0) e->istart = istart;
+  if (iend >= 0)   e->iend = iend;
+  if (istep >= 0)  e->istep = istep;
+  if (start >= 0. || istart < 0)
+    e->t = e->start;
+  else
+    e->t = e->start = G_MAXDOUBLE/2.;
+  if (istart >= 0 || start < 0.)
+    e->i = e->istart;
+  else
+    e->i = e->istart = G_MAXINT/2;
+}
+
+/**
+ * gfs_event_init:
+ * @event: a #GfsEvent.
+ * @sim: a #GfsSimulation.
+ *
+ * Initalizes @event associated with @sim. In particular, if @event is
+ * an "init" event it is activated by this function.
+ */
+void gfs_event_init (GfsEvent * event,
+		     GfsSimulation * sim)
+{
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (sim != NULL);
+
+  if (event->start < 0.) { /* "init" event */
+    g_assert (GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event);
+    (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event) (event, sim);
+  }
+  else if (event->end_event)
+    event->t = event->start = G_MAXDOUBLE/2.;
+  else {
+    if (event->istep < G_MAXINT)
+      while (event->i < sim->time.i) {
+	event->n++;
+	event->i += event->istep;
+      }
+    else
+      while (event->t < sim->time.t) {
+	event->n++;
+	event->t = event->start + event->n*event->step;
+      }
+  }
+}
+
+/**
+ * gfs_event_do:
+ * @event: a #GfsEvent:
+ * @sim: a #GfsSimulation.
+ * 
+ * Realises the event if active.
+ */
+void gfs_event_do (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsEventClass * klass;
+
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (sim != NULL);
+  
+  gchar * name = GTS_OBJECT (event)->klass->info.name;
+  gfs_domain_timer_start (GFS_DOMAIN (sim), name);
+
+  klass = GFS_EVENT_CLASS (GTS_OBJECT (event)->klass);
+  g_assert (klass->event);
+  if ((* klass->event) (event, sim) && klass->post_event)
+    (* klass->post_event) (event, sim);
+
+  gfs_domain_timer_stop (GFS_DOMAIN (sim), name);
+}
+
+/**
+ * gfs_event_half_do:
+ * @event: a #GfsEvent:
+ * @sim: a #GfsSimulation.
+ * 
+ * Realises the half-event if active.
+ */
+void gfs_event_half_do (GfsEvent * event, GfsSimulation * sim)
+{
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (sim != NULL);
+
+  if (event->realised && GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half)
+    (* GFS_EVENT_CLASS (GTS_OBJECT (event)->klass)->event_half) (event, sim);
+}
+
+/**
+ * gfs_event_redo:
+ * @event: a #GfsEvent:
+ * @sim: a #GfsSimulation.
+ * 
+ * Realises the event if it has just been realised.
+ */
+void gfs_event_redo (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsEventClass * klass;
+
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (sim != NULL);
+
+  klass = GFS_EVENT_CLASS (GTS_OBJECT (event)->klass);
+  g_assert (klass->event);
+  event->redo = TRUE;
+  if ((* klass->event) (event, sim) && klass->post_event)
+    (* klass->post_event) (event, sim);
+}
+
+/* GfsGenericInit: Object */
+
+static void gfs_generic_init_init (GfsEvent * event)
+{
+  event->start = -1;
+}
+
+GfsEventClass * gfs_generic_init_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_generic_init_info = {
+      "GfsGenericInit",
+      sizeof (GfsEvent),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) gfs_generic_init_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_generic_init_info);
+  }
+
+  return klass;
+}
+
+/* GfsInit: Object */
+
+typedef struct {
+  GfsVariable * v;
+  GfsFunction * f;
+} VarFunc;
+
+static VarFunc * var_func_new (GfsVariable * v, GfsFunction * f)
+{
+  VarFunc * vf = g_malloc (sizeof (VarFunc));
+  vf->v = v;
+  vf->f = f;
+  gfs_function_set_units (vf->f, vf->v->units);
+  return vf;
+}
+
+static void var_func_destroy (VarFunc * v)
+{
+  gts_object_destroy (GTS_OBJECT (v->f));
+  g_free (v);
+}
+
+static void gfs_init_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_init_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_init_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a variable name");
+      return;
+    }
+    else {
+      GfsInit * init = GFS_INIT (*o);
+      GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+      GfsVariable * v = gfs_domain_get_or_add_variable (domain, fp->token->str, NULL);
+      GfsFunction * f;
+
+      if (!v) {
+	gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+	return;
+      }
+      gts_file_next_token (fp);
+
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+
+      f = gfs_function_new (gfs_function_class (), 0.);
+      gfs_function_read (f, gfs_object_simulation (*o), fp);
+      if (fp->type == GTS_ERROR) {
+	gts_object_destroy (GTS_OBJECT (f));
+	return;
+      }
+      init->f = g_slist_append (init->f, var_func_new (v, f));
+    }
+  }
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+
+  GfsEvent * event = GFS_EVENT (*o);
+  if (event->start < 0. && (event->istep < G_MAXINT || event->step < G_MAXDOUBLE))
+    event->start = 0.;
+}
+
+static void gfs_init_write (GtsObject * o, FILE * fp)
+{
+  GSList * i;
+  
+  if (GTS_OBJECT_CLASS (gfs_init_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_init_class ())->parent_class->write) 
+      (o, fp);
+
+  fputs (" {\n", fp);
+  i = GFS_INIT (o)->f;
+  while (i) {
+    VarFunc * v = i->data;
+    fprintf (fp, "  %s =", v->v->name);
+    gfs_function_write (v->f, fp);
+    fputc ('\n', fp);
+    i = i->next;
+  }
+  fputc ('}', fp);
+}
+
+static void gfs_init_destroy (GtsObject * object)
+{
+  GfsInit * i = GFS_INIT (object);
+
+  g_slist_foreach (i->f, (GFunc) var_func_destroy, NULL);
+  g_slist_free (i->f);
+
+  (* GTS_OBJECT_CLASS (gfs_init_class ())->parent_class->destroy) 
+    (object);
+}
+
+static void init_vf (FttCell * cell, VarFunc * vf)
+{
+  GFS_VALUE (cell, vf->v) = gfs_function_value (vf->f, cell);
+}
+
+static gboolean gfs_init_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_class ())->parent_class)->event) 
+      (event, sim)) {
+    GSList * i = GFS_INIT (event)->f;
+
+    while (i) {
+      VarFunc * vf = i->data;
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) init_vf, vf);
+      i = i->next;
+    }
+    /* boundary conditions need to be called in a separate loop so
+       that they are correctly applied for vector quantities */
+    i = GFS_INIT (event)->f;
+    while (i) {
+      VarFunc * vf = i->data;
+      gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1, vf->v);
+      i = i->next;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_init_class_init (GfsGenericInitClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_init_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_init_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_init_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_init_destroy;
+}
+
+GfsGenericInitClass * gfs_init_class (void)
+{
+  static GfsGenericInitClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_info = {
+      "GfsInit",
+      sizeof (GfsInit),
+      sizeof (GfsGenericInitClass),
+      (GtsObjectClassInitFunc) gfs_init_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_init_info);
+  }
+
+  return klass;
+}
+
+/* GfsInitFlowConstant: Object: fixme: deprecated */
+
+static void gfs_init_flow_constant_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_init_flow_constant_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_init_flow_constant_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  g_warning ("GfsInitFlowConstant is deprecated you should use GfsInit instead");
+}
+
+static void gfs_init_flow_constant_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_init_flow_constant_read;
+}
+
+GfsEventClass * gfs_init_flow_constant_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_flow_constant_info = {
+      "GfsInitFlowConstant",
+      sizeof (GfsInit),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_init_flow_constant_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_init_class ()),
+				  &gfs_init_flow_constant_info);
+  }
+
+  return klass;
+}
+
+#if FTT_2D
+
+/* GfsInitVorticity: Object */
+
+static void gfs_init_vorticity_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_init_vorticity_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_init_vorticity_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  gfs_function_read (GFS_INIT_VORTICITY (*o)->f, gfs_object_simulation (*o), fp);
+}
+
+static void gfs_init_vorticity_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_init_vorticity_class ())->parent_class->write) (o, fp);
+  gfs_function_write (GFS_INIT_VORTICITY (o)->f, fp);
+}
+
+static void gfs_init_vorticity_destroy (GtsObject * object)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_INIT_VORTICITY (object)->f));
+  (* GTS_OBJECT_CLASS (gfs_init_vorticity_class ())->parent_class->destroy) (object);
+}
+
+static void sum_volume (FttCell * cell, GtsRange * vol)
+{
+  gdouble size = ftt_cell_size (cell);
+  
+  if (GFS_IS_MIXED (cell))
+    gts_range_add_value (vol, size*size*GFS_STATE (cell)->solid->a);
+  else
+    gts_range_add_value (vol, size*size);
+}
+
+static void add_ddiv (FttCell * cell, gpointer * data)
+{
+  gdouble * ddiv = data[0];
+  GfsVariable * div = data[1];
+  gdouble size = ftt_cell_size (cell);
+  
+  if (GFS_IS_MIXED (cell))
+    GFS_VARIABLE (cell, div->i) += size*size*GFS_STATE (cell)->solid->a*(*ddiv);
+  else
+    GFS_VARIABLE (cell, div->i) += size*size*(*ddiv);
+}
+
+static void correct_div (GfsDomain * domain, GfsVariable * v)
+{
+  GtsRange div, vol;
+  gdouble ddiv;
+  gpointer data[2];
+
+  div = gfs_domain_stats_variable (domain, v, FTT_TRAVERSE_LEAFS, -1);
+  gts_range_init (&vol);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) sum_volume, &vol);
+  gts_range_update (&vol);
+  ddiv = - div.mean/vol.mean;
+
+  data[0] = &ddiv;
+  data[1] = v;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) add_ddiv, data);
+}
+
+static void stream_from_vorticity (GfsDomain * domain,
+				   GfsVariable * stream,
+				   GfsVariable * vorticity,
+				   gdouble tolerance)
+{
+  GfsNorm norm;
+  guint maxit = 100;
+  GfsVariable * res, * dia;
+  GfsMultilevelParams par;
+
+  g_return_if_fail (domain != NULL);
+
+  dia = gfs_temporary_variable (domain);
+  gfs_poisson_coefficients (domain, NULL);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, dia);
+  correct_div (domain, vorticity); /* enforce solvability condition */
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, stream);
+  res = gfs_temporary_variable (domain);
+  gfs_residual (domain, FTT_DIMENSION, FTT_TRAVERSE_LEAFS, -1, stream, vorticity, dia, res);
+  norm = gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, 1., res);
+  gfs_multilevel_params_init (&par);
+  par.depth = gfs_domain_depth (domain);
+  while (norm.infty > tolerance && maxit) {
+    gfs_poisson_cycle (domain, &par, stream, vorticity, dia, res);
+    norm = gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, 1., res);
+    maxit--;
+  }
+  if (maxit == 0)
+    g_warning ("GfsInitVorticity: cannot solve streamfunction from vorticity\n"
+	       "  (residual: %g)", norm.infty);
+  gts_object_destroy (GTS_OBJECT (res));
+  gts_object_destroy (GTS_OBJECT (dia));
+}
+
+static void init_from_streamfunction (FttCell * cell, GfsInitVorticity * init)
+{
+  gdouble size = ftt_cell_size (cell);
+
+  GFS_VARIABLE (cell, init->u[0]->i) = - gfs_center_gradient (cell, FTT_Y, init->stream->i)/size;
+  GFS_VARIABLE (cell, init->u[1]->i) = gfs_center_gradient (cell, FTT_X, init->stream->i)/size;
+}
+
+static void compute_vorticity (FttCell * cell, GfsInitVorticity * init)
+{
+  gdouble size = ftt_cell_size (cell);
+
+  GFS_VARIABLE (cell, init->vort->i) = gfs_function_value (init->f, cell)*size*size;  
+}
+
+static gboolean gfs_init_vorticity_event (GfsEvent * event, 
+					  GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_vorticity_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsInitVorticity * init = GFS_INIT_VORTICITY (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+
+    init->vort = gfs_temporary_variable (domain);
+    init->stream = gfs_temporary_variable (domain);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) compute_vorticity, event);
+    stream_from_vorticity (domain, init->stream, init->vort, 1e-9);
+    gts_object_destroy (GTS_OBJECT (init->vort));
+    init->u = gfs_domain_velocity (domain);
+    gfs_domain_cell_traverse (domain, 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) init_from_streamfunction, init);
+    gts_object_destroy (GTS_OBJECT (init->stream));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_init_vorticity_class_init (GtsObjectClass * klass)
+{
+  klass->read = gfs_init_vorticity_read;
+  klass->write = gfs_init_vorticity_write;
+  klass->destroy = gfs_init_vorticity_destroy;
+  GFS_EVENT_CLASS (klass)->event = gfs_init_vorticity_event;
+}
+
+static void gfs_init_vorticity_init (GfsInitVorticity * init)
+{
+  init->f = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsGenericInitClass * gfs_init_vorticity_class (void)
+{
+  static GfsGenericInitClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_vorticity_info = {
+      "GfsInitVorticity",
+      sizeof (GfsInitVorticity),
+      sizeof (GfsGenericInitClass),
+      (GtsObjectClassInitFunc) gfs_init_vorticity_class_init,
+      (GtsObjectInitFunc) gfs_init_vorticity_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_init_vorticity_info);
+  }
+
+  return klass;
+}
+
+#endif /* FTT_2D */
+
+/* GfsEventSum: Object */
+
+static void gfs_event_sum_destroy (GtsObject * o)
+{
+  GfsEventSum * s = GFS_EVENT_SUM (o);
+
+  gts_object_destroy (GTS_OBJECT (s->v));
+
+  (* GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_event_sum_write (GtsObject * o, FILE * fp)
+{
+  GfsEventSum * s = GFS_EVENT_SUM (o);
+
+  (* GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class->write) (o, fp);
+
+  gfs_function_write (s->v, fp);
+  fprintf (fp, " %s", s->sv->name);
+}
+
+static void gfs_event_sum_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventSum * s = GFS_EVENT_SUM (*o);
+  GfsDomain * domain =  GFS_DOMAIN (gfs_object_simulation (s));
+
+  (* GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_function_read (s->v, domain, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (sv)");
+    return;
+  }
+  if (!(s->sv = gfs_domain_get_or_add_variable (domain, fp->token->str, "Sum"))) {
+    gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+}
+
+static gboolean gfs_event_sum_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsEventSum * s = GFS_EVENT_SUM (event);
+
+    if (s->last < 0.)
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) gfs_cell_reset, s->sv);
+    else {
+      s->dt = sim->time.t - s->last;
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				s->sum, s);
+    }
+    s->last = sim->time.t;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_sum_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_sum_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_sum_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_event_sum_destroy;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_sum_event;
+}
+
+static void sum (FttCell * cell, GfsEventSum * s)
+{
+  GFS_VARIABLE (cell, s->sv->i) += s->dt*gfs_function_value (s->v, cell);
+}
+
+static void gfs_event_sum_init (GfsEventSum * object)
+{
+  object->last = -1.;
+  object->v = gfs_function_new (gfs_function_class (), 0.);
+  object->sum = (FttCellTraverseFunc) sum;
+}
+
+GfsEventClass * gfs_event_sum_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_sum_info = {
+      "GfsEventSum",
+      sizeof (GfsEventSum),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_sum_class_init,
+      (GtsObjectInitFunc) gfs_event_sum_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_sum_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventSumDirection: Object */
+
+static void gfs_event_sum_direction_write (GtsObject * o, FILE * fp)
+{
+  GfsEventSumDirection * s = GFS_EVENT_SUM_DIRECTION (o);
+
+  (* GTS_OBJECT_CLASS (gfs_event_sum_direction_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s", ftt_direction_name [s->d]);
+}
+
+static void gfs_event_sum_direction_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventSumDirection * s = GFS_EVENT_SUM_DIRECTION (*o);
+
+  (* GTS_OBJECT_CLASS (gfs_event_sum_direction_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (direction)");
+    return;
+  }
+  s->d = ftt_direction_from_name (fp->token->str);
+  if (s->d >= FTT_NEIGHBORS) {
+    gts_file_error (fp, "unknown direction `%s'", fp->token->str);
+    s->d = 0;
+    return;
+  }
+  gts_file_next_token (fp);
+}
+
+static gboolean gfs_event_sum_direction_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsEventSumDirection * s = GFS_EVENT_SUM_DIRECTION (event);
+
+    gfs_domain_sum (GFS_DOMAIN (sim), s->d, GFS_EVENT_SUM (event)->v, GFS_EVENT_SUM (event)->sv);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_sum_direction_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_sum_direction_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_sum_direction_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_sum_direction_event;
+}
+
+GfsEventClass * gfs_event_sum_direction_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_sum_direction_info = {
+      "GfsEventSumDirection",
+      sizeof (GfsEventSumDirection),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_sum_direction_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_sum_class ()),
+				  &gfs_event_sum_direction_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventHarmonic: Object */
+
+static void gfs_event_harmonic_destroy (GtsObject * o)
+{
+  GfsEventHarmonic * s = GFS_EVENT_HARMONIC (o);
+
+  if (s->Mn)
+    gfs_matrix_free (s->Mn);
+  if (s->M)
+    gfs_matrix_free (s->M);
+  if (s->iM)
+    gfs_matrix_free (s->iM);
+
+  g_free (s->A);
+  g_free (s->B);
+  g_free (s->vsin);
+  g_free (s->vcos);
+  g_free (s->x);
+  g_free (s->a);
+
+  g_free (s->Aname);
+  g_free (s->Bname);
+
+  g_array_free (s->omega, TRUE);
+
+  (* GTS_OBJECT_CLASS (gfs_event_harmonic_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_event_harmonic_write (GtsObject * o, FILE * fp)
+{
+  GfsEventHarmonic * s = GFS_EVENT_HARMONIC (o);
+  guint i, j;
+
+  (* GTS_OBJECT_CLASS (gfs_event_harmonic_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s %s %s %s", s->v->name, s->Aname, s->Bname, s->z->name);
+  if (s->e)
+    fprintf (fp, " %s", s->e->name);
+  for (i = 0; i < s->omega->len; i++)
+    fprintf (fp, " %.12lf", g_array_index (s->omega, gdouble, i));
+  fprintf (fp, " { %d", s->invertible);
+  for (i = 0; i < 2*s->omega->len + 1; i++)
+    for (j = 0; j < 2*s->omega->len + 1; j++)
+      fprintf (fp, " %.12lf", s->M[i][j]);
+  fputs (" }", fp);
+}
+
+static void gfs_event_harmonic_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventHarmonic * s = GFS_EVENT_HARMONIC (*o);
+  GfsDomain * domain =  GFS_DOMAIN (gfs_object_simulation (s));
+  guint i;
+
+  (* GTS_OBJECT_CLASS (gfs_event_harmonic_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (v)");
+    return;
+  }
+  if (!(s->v = gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (A)");
+    return;
+  }
+  s->Aname = g_strdup (fp->token->str);  
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (B)");
+    return;
+  }
+  s->Bname = g_strdup (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (Z)");
+    return;
+  }
+  if (!(s->z = gfs_domain_get_or_add_variable (domain, fp->token->str, 
+					       "Offset of harmonic decomposition"))) {
+    gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+    return;
+  }
+  s->z->units = s->v->units;
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a string (E)");
+      return;
+    }
+    if (!(s->e = gfs_domain_get_or_add_variable (domain, fp->token->str, 
+						 "Remainder of harmonic decomposition"))) {
+      gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+      return;
+    }
+    s->e->units = s->v->units;
+    gts_file_next_token (fp);
+  }
+
+  do {
+    gdouble omega = gfs_read_constant (fp, domain);
+    if (fp->type == GTS_ERROR)      
+      return;
+    g_array_append_val (s->omega, omega);
+  } while (fp->type != '\n' && fp->type != '{');
+
+  s->Mn = gfs_matrix_new (2*s->omega->len + 1, 2*s->omega->len + 1, sizeof (gdouble));
+  for (i = 0; i < 2*s->omega->len + 1; i++)
+    s->Mn[i][i] = 1.;
+
+  s->M  = gfs_matrix_new (2*s->omega->len + 1, 2*s->omega->len + 1, sizeof (gdouble));
+  s->iM = gfs_matrix_new (2*s->omega->len + 1, 2*s->omega->len + 1, sizeof (gdouble));
+
+  s->A =    g_malloc (sizeof (GfsVariable *)*s->omega->len);
+  s->B =    g_malloc (sizeof (GfsVariable *)*s->omega->len);
+  s->vsin = g_malloc (sizeof (gdouble)*s->omega->len);
+  s->vcos = g_malloc (sizeof (gdouble)*s->omega->len);
+  s->x    = g_malloc (sizeof (gdouble)*(2*s->omega->len + 1));
+  s->a    = g_malloc (sizeof (gdouble)*(2*s->omega->len + 1));
+
+  for (i = 0; i < s->omega->len; i++) {
+    gchar * u;
+    
+    u = g_strdup_printf ("%s%d", s->Aname, i);
+    if (!(s->A[i] = gfs_domain_get_or_add_variable (domain, u, 
+					"In-phase component of the harmonic decomposition"))) {
+      gts_file_error (fp, "`%s' is a reserved keyword", u);
+      return;
+    }
+    s->A[i]->units = s->v->units;
+    g_free (u);
+    u = g_strdup_printf ("%s%d", s->Bname, i);
+    if (!(s->B[i] = gfs_domain_get_or_add_variable (domain, u,
+				       "Out-of-phase component of the harmonic decomposition"))) {
+      gts_file_error (fp, "`%s' is a reserved keyword", u);
+      return;
+    }
+    s->B[i]->units = s->v->units;
+    g_free (u);
+  }
+
+  if (fp->type == '{') {
+    guint n = 2*s->omega->len + 1;
+    guint j;
+
+    fp->scope_max++;
+    gts_file_next_token (fp);
+    if (fp->type != GTS_INT) {
+      gts_file_error (fp, "expecting a number (invertible)");
+      return;
+    }
+    s->invertible = atoi (fp->token->str);
+    gts_file_next_token (fp);
+    for (i = 0; i < n; i++)
+      for (j = 0; j < n; j++)
+	if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+	  gts_file_error (fp, "expecting a number (M[%d][%d])", i, j);
+	  return;
+	}
+	else {
+	  s->M[i][j] = atof (fp->token->str);
+	  gts_file_next_token (fp);
+	}
+    if (fp->type != '}') {
+      gts_file_error (fp, "expecting a closing brace");
+      return;
+    }
+    gts_file_next_token (fp);
+    fp->scope_max--;
+
+    if (s->invertible)
+      for (i = 0; i < n; i++)
+	for (j = 0; j < n; j++)
+	  s->Mn[i][j] = s->M[i][j];
+  }
+}
+
+static void add_xsin_xcos (FttCell * cell, GfsEventHarmonic * h)
+{
+  gdouble x = GFS_VARIABLE (cell, h->v->i);
+  guint i;
+
+  for (i = 0; i < h->omega->len; i++) {
+    GFS_VARIABLE (cell, h->A[i]->i) += x*h->vcos[i];
+    GFS_VARIABLE (cell, h->B[i]->i) += x*h->vsin[i];
+  }
+  GFS_VARIABLE (cell, h->z->i) += x;
+  if (h->e)
+    GFS_VARIABLE (cell, h->e->i) += x*x;
+}
+
+static gdouble de (GfsEventHarmonic * h, gdouble ** M)
+{
+  guint n = h->omega->len;
+  gdouble xm = h->a[2*n];
+  gdouble e = xm*(M[2*n][2*n]*xm - 2.*h->x[2*n]);
+  guint i, j;
+
+  for (i = 0; i < n; i++) {
+    e += 2.*(h->a[i]*(xm*M[i][2*n] - h->x[i]) +
+	     h->a[n + i]*(xm*M[n + i][2*n] - h->x[n + i]));
+    for (j = 0; j < n; j++)
+      e += (h->a[i]*h->a[j]*M[j][i] + 
+	    h->a[n + i]*h->a[n + j]*M[n + j][n + i] +
+	    2.*h->a[i]*h->a[n + j]*M[n + j][i]);
+  }
+  return e;
+}
+
+static void update_A_B_Z (FttCell * cell, GfsEventHarmonic * h)
+{
+  gdouble x = GFS_VARIABLE (cell, h->v->i), sx2 = 0.;
+  guint n = h->omega->len;
+  guint i, j;
+
+  /* A^n */
+  for (i = 0; i < n; i++) {
+    h->a[i] =     GFS_VARIABLE (cell, h->A[i]->i);
+    h->a[i + n] = GFS_VARIABLE (cell, h->B[i]->i);
+  }
+  h->a[2*n] = GFS_VARIABLE (cell, h->z->i);
+
+  /* X^n = M^n.A^n */
+  for (i = 0; i < 2*n + 1; i++) {
+    h->x[i] = 0.;
+    for (j = 0; j < 2*n + 1; j++)
+      h->x[i] += h->Mn[i][j]*h->a[j];
+  }
+
+  if (h->e) {
+    if (h->invertible)
+      sx2 = x*x + h->Mn[2*n][2*n]*GFS_VARIABLE (cell, h->e->i) - de (h, h->Mn);
+    else
+      sx2 = x*x + GFS_VARIABLE (cell, h->e->i);
+  }
+  
+  /* X^n+1 = X^n + Delta^n */
+  for (i = 0; i < n; i++) {
+    h->x[i]     += x*h->vcos[i];
+    h->x[i + n] += x*h->vsin[i];
+  }
+  h->x[2*n] += x;
+
+  /* A^n+1 = (M^n+1)^-1.X^n+1 */
+  for (i = 0; i < 2*n + 1; i++) {
+    h->a[i] = 0.;
+    for (j = 0; j < 2*n + 1; j++)
+      h->a[i] += h->iM[i][j]*h->x[j];
+  }
+
+  for (i = 0; i < n; i++) {
+    GFS_VARIABLE (cell, h->A[i]->i) = h->a[i];
+    GFS_VARIABLE (cell, h->B[i]->i) = h->a[i + n];
+  }
+  GFS_VARIABLE (cell, h->z->i) = h->a[2*n];
+
+  if (h->e)
+    GFS_VARIABLE (cell, h->e->i) = (sx2 + de (h, h->M))/h->M[2*n][2*n];
+}
+
+static gboolean gfs_event_harmonic_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_harmonic_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsEventHarmonic * h = GFS_EVENT_HARMONIC (event);
+    gdouble ** M = h->M, * vsin = h->vsin, * vcos = h->vcos;
+    gdouble ** iM = h->iM, ** Mn = h->Mn;
+    guint i, j, n = h->omega->len;
+
+    for (i = 0; i < n; i++) {
+      vsin[i] = sin (g_array_index (h->omega, gdouble, i)*sim->time.t);
+      vcos[i] = cos (g_array_index (h->omega, gdouble, i)*sim->time.t);
+    }
+
+    for (i = 0; i < n; i++) {
+      for (j = 0; j < n; j++) {
+        M[i][j]         += vcos[j]*vcos[i];
+	M[i][n + j]     += vsin[j]*vcos[i];
+        M[n + i][j]     += vcos[j]*vsin[i];
+	M[n + i][n + j] += vsin[j]*vsin[i];
+      }
+      M[i][2*n]     += vcos[i];
+      M[n + i][2*n] += vsin[i];
+    }
+    for (j = 0; j < n; j++) {
+      M[2*n][j]     += vcos[j];
+      M[2*n][n + j] += vsin[j];
+    }
+    M[2*n][2*n] += 1.;
+
+    for (i = 0; i < 2*n + 1; i++)
+      for (j = 0; j < 2*n + 1; j++)
+	iM[i][j] = M[i][j];
+
+    if (!gfs_matrix_inverse (iM, 2*n + 1, 1e-6)) {
+      g_assert (!h->invertible);
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) add_xsin_xcos, h);
+    }
+    else {
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) update_A_B_Z, h);
+      h->invertible = TRUE;
+      for (i = 0; i < 2*n + 1; i++)
+	for (j = 0; j < 2*n + 1; j++)
+	  Mn[i][j] = M[i][j];
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_harmonic_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = gfs_event_harmonic_destroy;
+  klass->read = gfs_event_harmonic_read;
+  klass->write = gfs_event_harmonic_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_harmonic_event;
+}
+
+static void gfs_event_harmonic_init (GfsEventHarmonic * object)
+{
+  object->omega = g_array_new (FALSE, FALSE, sizeof (gdouble));
+}
+
+GfsEventClass * gfs_event_harmonic_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_harmonic_info = {
+      "GfsEventHarmonic",
+      sizeof (GfsEventHarmonic),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_harmonic_class_init,
+      (GtsObjectInitFunc) gfs_event_harmonic_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_harmonic_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventStop: Object */
+
+static void gfs_event_stop_write (GtsObject * o, FILE * fp)
+{
+  GfsEventStop * s = GFS_EVENT_STOP (o);
+
+  if (GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class->write)
+      (o, fp);
+
+  fprintf (fp, " %s %g", s->v->name, s->max);
+  if (s->diff)
+    fprintf (fp, " %s", s->diff->name);
+}
+
+static void gfs_event_stop_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventStop * s = GFS_EVENT_STOP (*o);
+  GfsDomain * domain =  GFS_DOMAIN (gfs_object_simulation (s));
+
+  if (GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (v)");
+    return;
+  }
+  if (!(s->v = gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  s->max = gfs_read_constant (fp, domain);
+  if (fp->type == GTS_ERROR)      
+    return;
+  s->oldv = gfs_domain_add_variable (domain, NULL, NULL);
+  /* fixme: the lines below are necessary in the general case (e.g. when dealing with a VOF tracer)
+   * but will crash if s->oldv is not of the same class as s->v.
+   * s->oldv->fine_coarse = s->v->fine_coarse;
+   * s->oldv->coarse_fine = s->v->coarse_fine;
+   */
+
+  if (fp->type == GTS_STRING) {
+    if (!(s->diff = gfs_domain_get_or_add_variable (domain, fp->token->str, 
+						    "Stopping field difference"))) {
+      gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+      return;
+    }
+    s->diff->units = s->v->units;
+    gts_file_next_token (fp);
+  }
+}
+
+static void gfs_event_stop_destroy (GtsObject * o)
+{
+  if (GFS_EVENT_STOP (o)->oldv)
+    gts_object_destroy (GTS_OBJECT (GFS_EVENT_STOP (o)->oldv));
+
+  (* GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class->destroy) (o);
+}
+
+static void diff (FttCell * cell, GfsEventStop * s)
+{
+  GFS_VALUE (cell, s->oldv) -= GFS_VALUE (cell, s->v);
+}
+
+static void copy (FttCell * cell, GfsEventStop * s)
+{
+  GFS_VALUE (cell, s->oldv) = GFS_VALUE (cell, s->v);
+}
+
+static gboolean gfs_event_stop_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_stop_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsEventStop * s = GFS_EVENT_STOP (event);
+
+    if (s->last >= 0.) {
+      GfsNorm n;
+
+      gfs_domain_cell_traverse (domain,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) diff, s);
+      n = gfs_domain_norm_variable (domain, s->oldv, NULL, FTT_TRAVERSE_LEAFS, -1);
+      if (gfs_dimensional_value (s->v, n.infty) <= s->max)
+	sim->time.end = sim->time.t;
+      if (s->diff) {
+	gfs_variables_swap (s->diff, s->oldv);
+	gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, s->diff);
+      }
+    }
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) copy, s);
+    gfs_domain_copy_bc (domain, FTT_TRAVERSE_LEAFS, -1, s->v, s->oldv);
+    s->last = sim->time.t;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_stop_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_stop_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_stop_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_event_stop_destroy;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_stop_event;
+}
+
+static void gfs_event_stop_init (GfsEventStop * object)
+{
+  object->last = -1.;
+}
+
+GfsEventClass * gfs_event_stop_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_stop_info = {
+      "GfsEventStop",
+      sizeof (GfsEventStop),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_stop_class_init,
+      (GtsObjectInitFunc) gfs_event_stop_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_stop_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventScript: Object */
+
+static void gfs_event_script_destroy (GtsObject * o)
+{
+  GfsEventScript * s = GFS_EVENT_SCRIPT (o);
+
+  g_free (s->script);
+
+  (* GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class->destroy) (o);
+} 
+
+static void gfs_event_script_write (GtsObject * o, FILE * fp)
+{
+  GfsEventScript * s = GFS_EVENT_SCRIPT (o);
+
+  if (GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class->write)
+      (o, fp);
+
+  fputs (" {", fp);
+  if (s->script)
+    fputs (s->script, fp);
+  fputc ('}', fp);
+}
+
+static void gfs_event_script_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsEventScript * s = GFS_EVENT_SCRIPT (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  g_free (s->script);
+  if ((s->script = gfs_file_statement (fp)))
+    gts_file_next_token (fp);
+}
+
+/**
+ * gfs_popen:
+ * @sim: a #GfsSimulation.
+ * @command: a shell command.
+ * @type: "r" for reading or "w" for writing.
+ *
+ * Returns: a file descriptor pointing to a pipe opened using the
+ * standard popen() command but which also defines standard Gerris
+ * shell variables. In case of error returns %NULL.
+ */
+FILE * gfs_popen (GfsSimulation * sim, const char * command, const char * type)
+{
+  g_return_val_if_fail (command != NULL, NULL);
+  g_return_val_if_fail (type != NULL, NULL);
+  
+  gchar sname[] = "/tmp/gfsXXXXXX";
+  if (!mktemp (sname)) {
+    g_warning ("gfs_popen() cannot create unique temporary filename");
+    return NULL;
+  }
+  if (mkfifo (sname, 0666)) {
+    g_warning ("gfs_popen() cannot create FIFO: %s", strerror (errno));
+    return NULL;
+  }
+  /* When adding pre-defined shell variables please update this page:
+     http://gfs.sourceforge.net/wiki/index.php/GfsEventScript */
+  gchar * scommand = g_strdup_printf ("GfsTime=%g GfsIter=%d GfsPid=%d "
+				      "GFS_STOP=%d sh %s",
+				      sim->time.t, sim->time.i, 
+				      GFS_DOMAIN (sim)->pid,
+				      GFS_EVENT_SCRIPT_STOP,
+				      sname);
+  fflush (stdout);
+  fflush (stderr);
+  FILE * fp = popen (scommand, type);
+  g_free (scommand);
+  if (fp != NULL) {
+    FILE * f = fopen (sname, "w");
+    fputs (command, f);
+    fclose (f);
+  }
+  remove (sname);
+  return fp;
+}
+
+static gboolean gfs_event_script_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_script_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsEventScript * s = GFS_EVENT_SCRIPT (event);
+    if (s->script && GFS_DOMAIN (sim)->pid <= 0) {
+      FILE * fp = gfs_popen (sim, s->script, "w");
+      if (fp == NULL) {
+	g_warning ("GfsEventScript cannot start script");
+	return TRUE;
+      }
+      int status = pclose (fp);
+      if (status != -1)
+	status = WEXITSTATUS (status);
+      if (status == GFS_EVENT_SCRIPT_STOP)
+	exit (1);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_script_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_event_script_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_script_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_script_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_event_script_event;
+}
+
+GfsEventClass * gfs_event_script_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_script_info = {
+      "GfsEventScript",
+      sizeof (GfsEventScript),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_script_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_script_info);
+  }
+
+  return klass;
+}
+
+/* GfsInitFraction: Object */
+
+static void gfs_init_fraction_destroy (GtsObject * object)
+{
+  GfsInitFraction * init = GFS_INIT_FRACTION (object);
+
+  gts_object_destroy (GTS_OBJECT (init->surface));
+
+  (* GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class->destroy) 
+    (object);
+}
+
+static void gfs_init_fraction_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsInitFraction * init;
+  GfsDomain * domain;
+
+  if (GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  init = GFS_INIT_FRACTION (*o);
+  domain =  GFS_DOMAIN (gfs_object_simulation (init));
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (variable)");
+    return;
+  }
+  if ((init->c = gfs_variable_from_name (domain->variables, fp->token->str))
+      == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  gfs_generic_surface_read (init->surface, gfs_object_simulation (*o), fp);
+}
+
+static void gfs_init_fraction_write (GtsObject * o, FILE * fp)
+{
+  GfsInitFraction * init = GFS_INIT_FRACTION (o);
+
+
+  (* GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s", init->c->name);
+  gfs_generic_surface_write (init->surface, gfs_object_simulation (o), fp);
+}
+
+static gboolean gfs_init_fraction_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_fraction_class ())->parent_class)->event) 
+      (event, sim)) {
+    gfs_domain_init_fraction (GFS_DOMAIN (sim), 
+			      GFS_INIT_FRACTION (event)->surface,
+			      GFS_INIT_FRACTION (event)->c);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_init_fraction_class_init (GfsInitFractionClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_init_fraction_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_init_fraction_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_init_fraction_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_init_fraction_destroy;
+}
+
+static void gfs_init_fraction_init (GfsInitFraction * object)
+{
+  object->surface = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+}
+
+GfsInitFractionClass * gfs_init_fraction_class (void)
+{
+  static GfsInitFractionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_fraction_info = {
+      "GfsInitFraction",
+      sizeof (GfsInitFraction),
+      sizeof (GfsInitFractionClass),
+      (GtsObjectClassInitFunc) gfs_init_fraction_class_init,
+      (GtsObjectInitFunc) gfs_init_fraction_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_init_fraction_info);
+  }
+
+  return klass;
+}
+
+/* GfsRemoveDroplets: Object */
+
+static void gfs_remove_droplets_destroy (GtsObject * object)
+{
+  GfsRemoveDroplets * d = GFS_REMOVE_DROPLETS (object);
+  if (d->fc)
+    gts_object_destroy (GTS_OBJECT (d->fc));
+  (* GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class->destroy) (object);
+}
+
+static void compute_v (FttCell * cell, GfsRemoveDroplets * d)
+{
+  GFS_VALUE (cell, d->v) = gfs_function_value (d->fc, cell);
+}
+
+static gboolean gfs_remove_droplets_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsRemoveDroplets * d = GFS_REMOVE_DROPLETS (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    d->v = d->fc ? gfs_function_get_variable (d->fc) : d->c;
+    if (d->v)
+      gfs_domain_remove_droplets (domain, d->v, d->c, d->min);
+    else {
+      d->v = gfs_temporary_variable (domain);
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+				(FttCellTraverseFunc) compute_v, d);
+      gfs_domain_remove_droplets (domain, d->v, d->c, d->min);
+      gts_object_destroy (GTS_OBJECT (d->v));
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_remove_droplets_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (variable)");
+    return;
+  }
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  GfsRemoveDroplets * r = GFS_REMOVE_DROPLETS (*o);
+  if ((r->c = gfs_variable_from_name (domain->variables, fp->token->str)) == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (min)");
+    return;
+  }
+  GFS_REMOVE_DROPLETS (*o)->min = atoi (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != '\n') {
+    r->fc = gfs_function_new (gfs_function_class (), 0.);
+    gfs_function_read (r->fc, gfs_object_simulation (r), fp);
+  }
+}
+
+static void gfs_remove_droplets_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_remove_droplets_class ())->parent_class->write) 
+      (o, fp);
+  GfsRemoveDroplets * r = GFS_REMOVE_DROPLETS (o);
+  fprintf (fp, " %s %d", r->c->name, r->min);
+  if (r->fc)
+    gfs_function_write (r->fc, fp);
+}
+
+static void gfs_remove_droplets_class_init (GfsEventClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_remove_droplets_event;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_remove_droplets_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_remove_droplets_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_remove_droplets_write;
+}
+
+GfsEventClass * gfs_remove_droplets_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_remove_droplets_info = {
+      "GfsRemoveDroplets",
+      sizeof (GfsRemoveDroplets),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_remove_droplets_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_remove_droplets_info);
+  }
+
+  return klass;
+}
+
+/* GfsRemovePonds: Object */
+
+static gboolean gfs_remove_ponds_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_remove_ponds_class ())->parent_class)->event) 
+      (event, sim)) {
+    gfs_domain_remove_ponds (GFS_DOMAIN (sim), GFS_REMOVE_PONDS (event)->min,
+			     (FttCellCleanupFunc) gfs_cell_cleanup, sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_remove_ponds_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_remove_ponds_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_remove_ponds_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (min)");
+    return;
+  }
+  GFS_REMOVE_PONDS (*o)->min = atoi (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void gfs_remove_ponds_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_remove_ponds_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_remove_ponds_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %d", GFS_REMOVE_PONDS (o)->min);
+}
+
+static void gfs_remove_ponds_class_init (GfsEventClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_remove_ponds_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_remove_ponds_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_remove_ponds_write;
+}
+
+GfsEventClass * gfs_remove_ponds_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_remove_ponds_info = {
+      "GfsRemovePonds",
+      sizeof (GfsRemovePonds),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_remove_ponds_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_remove_ponds_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventFilter: Object */
+
+static void filter (FttCell * cell, GfsEventFilter * f)
+{
+  FttDirection d[4*(FTT_DIMENSION - 1)][FTT_DIMENSION] = {
+#if FTT_2D
+    {FTT_RIGHT, FTT_TOP}, {FTT_RIGHT, FTT_BOTTOM}, {FTT_LEFT, FTT_TOP}, {FTT_LEFT, FTT_BOTTOM}
+#else
+    {FTT_RIGHT, FTT_TOP, FTT_FRONT}, {FTT_RIGHT, FTT_BOTTOM, FTT_FRONT}, 
+    {FTT_LEFT, FTT_TOP, FTT_FRONT}, {FTT_LEFT, FTT_BOTTOM, FTT_FRONT},
+    {FTT_RIGHT, FTT_TOP, FTT_BACK}, {FTT_RIGHT, FTT_BOTTOM, FTT_BACK}, 
+    {FTT_LEFT, FTT_TOP, FTT_BACK}, {FTT_LEFT, FTT_BOTTOM, FTT_BACK}
+#endif
+  };
+  guint i;
+  gdouble val = 0.;
+
+  for (i = 0; i < 4*(FTT_DIMENSION - 1); i++)
+    val += gfs_cell_corner_value (cell, d[i], f->v, -1);
+  GFS_VARIABLE (cell, f->tmp->i) = val/(4*(FTT_DIMENSION - 1));
+}
+
+static void filtered (FttCell * cell, GfsEventFilter * f)
+{
+  gdouble dt = gfs_object_simulation (f)->advection_params.dt/f->scale;
+  GFS_VALUE (cell, f->v) = ((1. - dt)*GFS_VALUE (cell, f->v) +
+			    dt*GFS_VALUE (cell, f->tmp));
+}
+
+static gboolean gfs_event_filter_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_filter_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsEventFilter * f = GFS_EVENT_FILTER (event);
+
+    f->tmp = gfs_temporary_variable (GFS_DOMAIN (sim));
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) filter, f);
+    gfs_traverse_and_bc (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			 (FttCellTraverseFunc) filtered, f,
+			 f->v, f->v);
+    gts_object_destroy (GTS_OBJECT (f->tmp));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_event_filter_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain;
+
+  if (GTS_OBJECT_CLASS (gfs_event_filter_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_event_filter_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (variable)");
+    return;
+  }
+  domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if ((GFS_EVENT_FILTER (*o)->v = gfs_variable_from_name (domain->variables, fp->token->str))
+      == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  GFS_EVENT_FILTER (*o)->scale = gfs_read_constant (fp, domain);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (GFS_EVENT_FILTER (*o)->scale <= 0.) {
+    gts_file_error (fp, "time scale must be strictly positive");
+    return;
+  }
+}
+
+static void gfs_event_filter_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_event_filter_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_event_filter_class ())->parent_class->write) 
+      (o, fp);
+  fprintf (fp, " %s %g", GFS_EVENT_FILTER (o)->v->name, GFS_EVENT_FILTER (o)->scale);
+}
+
+static void gfs_event_filter_class_init (GfsEventClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_event_filter_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_filter_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_filter_write;
+}
+
+GfsEventClass * gfs_event_filter_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_filter_info = {
+      "GfsEventFilter",
+      sizeof (GfsEventFilter),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_filter_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_filter_info);
+  }
+
+  return klass;
+}
+
+/* GfsEventList: Object */
+
+static gboolean gfs_event_list_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_list_class ())->parent_class)->event) 
+      (event, sim)) {
+    gts_container_foreach (GTS_CONTAINER (GFS_EVENT_LIST (event)->list), 
+			   (GtsFunc) gfs_event_do, sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void copy_event (GfsEvent * event, GfsEvent * list)
+{
+  gfs_event_set (event, list->start, list->end, list->step, list->istart, list->iend, list->istep);
+}
+
+static void gfs_event_list_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_event_list_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsEventList * l = GFS_EVENT_LIST (*o);
+  if (fp->type == GTS_STRING) {
+    l->klass = gfs_object_class_from_name (fp->token->str);
+    if (l->klass == NULL) {
+      gts_file_error (fp, "unknown class `%s'", fp->token->str);
+      return;
+    }
+    gts_file_next_token (fp);
+  }
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  while (fp->type == '\n') gts_file_next_token (fp);
+
+  GtsObjectClass * default_class = l->klass;
+  GfsSimulation * sim = gfs_object_simulation (*o);
+  while (fp->type != '}') {
+    GtsObjectClass * klass = default_class;
+    if (klass == NULL) {
+      if (fp->type != GTS_STRING) {
+	gts_file_error (fp, "expecting a keyword");
+	return;
+      }
+      klass = gfs_object_class_from_name (fp->token->str);
+      if (klass == NULL) {
+	gts_file_error (fp, "unknown class `%s'", fp->token->str);
+	return;
+      }
+      if (!gts_object_class_is_from_class (klass, gfs_event_class ())) {
+	gts_file_error (fp, "'%s' is not a GfsEvent", fp->token->str);
+	return;
+      }
+    }
+    
+    GtsObject * object = gts_object_new (klass);
+    gfs_object_simulation_set (object, sim);
+    (* klass->read) (&object, fp);
+    if (fp->type == GTS_ERROR) {
+      gts_object_destroy (object);
+      return;
+    }
+    while (fp->type == '\n') gts_file_next_token (fp);
+
+    gts_container_add (GTS_CONTAINER (l->list), GTS_CONTAINEE (object));
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+  
+  l->list->items = g_slist_reverse (l->list->items);
+  gts_container_foreach (GTS_CONTAINER (l->list), (GtsFunc) copy_event, l);
+}
+
+static void gfs_event_list_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_event_list_class ())->parent_class->write) (o, fp);
+  GfsEventList * l = GFS_EVENT_LIST (o);
+  if (l->klass)
+    fprintf (fp, " %s", l->klass->info.name);
+  fputs (" {\n", fp);
+  GSList * i = l->list->items;
+  while (i) {
+    fputs ("    ", fp);
+    (* GTS_OBJECT (i->data)->klass->write) (i->data, fp);
+    fputc ('\n', fp);
+    i = i->next;
+  }
+  fputc ('}', fp);
+}
+
+static void gfs_event_list_destroy (GtsObject * o)
+{
+  GfsEventList * l = GFS_EVENT_LIST (o);
+  gts_container_foreach (GTS_CONTAINER (l->list), (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (l->list));
+
+  (* GTS_OBJECT_CLASS (gfs_event_list_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_event_list_class_init (GfsEventClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_event_list_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_event_list_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_event_list_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_event_list_destroy;
+}
+
+static void gfs_event_list_init (GfsEventList * l)
+{
+  l->list = 
+    GTS_SLIST_CONTAINER (gts_container_new (GTS_CONTAINER_CLASS (gts_slist_container_class ())));
+}
+
+GfsEventClass * gfs_event_list_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_event_list_info = {
+      "GfsEventList",
+      sizeof (GfsEventList),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_event_list_class_init,
+      (GtsObjectInitFunc) gfs_event_list_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_event_list_info);
+  }
+
+  return klass;
+}
+
diff --git a/src/event.h b/src/event.h
new file mode 100644
index 0000000..feec3df
--- /dev/null
+++ b/src/event.h
@@ -0,0 +1,366 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __EVENT_H__
+#define __EVENT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gts.h>
+
+typedef struct _GfsEvent                GfsEvent;
+typedef struct _GfsEventClass           GfsEventClass;
+
+struct _GfsEvent {
+  GtsSListContainee parent;
+
+  gdouble t, start, end, step;
+  guint i, istart, iend, istep;
+  
+  guint n;
+  gboolean end_event, realised, redo;
+};
+
+typedef struct _GfsSimulation           GfsSimulation;
+
+struct _GfsEventClass {
+  GtsSListContaineeClass parent_class;
+
+  gboolean (* event)      (GfsEvent * event, GfsSimulation * sim);
+  void     (* post_event) (GfsEvent * event, GfsSimulation * sim);
+  void     (* event_half) (GfsEvent * event, GfsSimulation * sim);
+};
+
+#include "simulation.h"
+
+#define GFS_EVENT(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsEvent,\
+					           gfs_event_class ())
+#define GFS_EVENT_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsEventClass,\
+						   gfs_event_class())
+#define GFS_IS_EVENT(obj)         (gts_object_is_from_class (obj,\
+						   gfs_event_class ()))
+
+GfsEventClass * gfs_event_class       (void);
+GfsEvent *      gfs_event_new         (GfsEventClass * klass);
+void            gfs_event_set         (GfsEvent * e, 
+				       gdouble start, 
+				       gdouble end, 
+				       gdouble step,
+				       gint istart, 
+				       gint iend, 
+				       gint istep);
+void            gfs_event_init        (GfsEvent * event,
+				       GfsSimulation * sim);
+void            gfs_event_do          (GfsEvent * event, 
+				       GfsSimulation * sim);
+void            gfs_event_redo        (GfsEvent * event, 
+				       GfsSimulation * sim);
+gdouble         gfs_event_next        (GfsEvent * event, 
+				       GfsSimulation * sim);
+void            gfs_event_half_do     (GfsEvent * event, 
+				       GfsSimulation * sim);
+#define         gfs_event_is_repetitive(e) ((e)->step < G_MAXDOUBLE || (e)->istep < G_MAXINT)
+
+/* GfsGenericInit: Header */
+
+typedef struct _GfsEvent      GfsGenericInit;
+typedef struct _GfsEventClass GfsGenericInitClass;
+
+#define GFS_IS_GENERIC_INIT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_generic_init_class ()))
+
+GfsEventClass * gfs_generic_init_class         (void);
+
+/* GfsInit: Header */
+
+typedef struct _GfsInit         GfsInit;
+
+struct _GfsInit {
+  /*< private >*/
+  GfsGenericInit parent;
+  GSList * f;
+};
+
+#define GFS_INIT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsInit,\
+					         gfs_init_class ())
+#define GFS_IS_INIT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_init_class ()))
+
+GfsGenericInitClass * gfs_init_class  (void);
+
+/* GfsInitFlowConstant: Header */
+
+GfsEventClass * gfs_init_flow_constant_class  (void);
+
+#if FTT_2D
+
+/* GfsInitVorticity: Header */
+
+typedef struct _GfsInitVorticity         GfsInitVorticity;
+
+struct _GfsInitVorticity {
+  /*< private >*/
+  GfsGenericInit parent;
+  GfsVariable * vort, * stream, ** u;
+
+  /*< public >*/
+  GfsFunction * f;
+};
+
+#define GFS_INIT_VORTICITY(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsInitVorticity,\
+					         gfs_init_vorticity_class ())
+#define GFS_IS_INIT_VORTICITY(obj)         (gts_object_is_from_class (obj,\
+						 gfs_init_vorticity_class ()))
+
+GfsGenericInitClass * gfs_init_vorticity_class  (void);
+
+#endif /* FTT_2D */
+
+/* GfsEventSum: Header */
+
+typedef struct _GfsEventSum         GfsEventSum;
+
+struct _GfsEventSum {
+  GfsEvent parent;
+
+  GfsFunction * v;
+  GfsVariable * sv;
+  FttCellTraverseFunc sum;
+  gdouble last, dt;
+};
+
+#define GFS_EVENT_SUM(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventSum,\
+					         gfs_event_sum_class ())
+#define GFS_IS_EVENT_SUM(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_sum_class ()))
+
+GfsEventClass * gfs_event_sum_class  (void);
+
+/* GfsEventSumDirection: Header */
+
+typedef struct _GfsEventSumDirection         GfsEventSumDirection;
+
+struct _GfsEventSumDirection {
+  GfsEventSum parent;
+
+  FttDirection d;
+};
+
+#define GFS_EVENT_SUM_DIRECTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventSumDirection,\
+					         gfs_event_sum_direction_class ())
+#define GFS_IS_EVENT_SUM_DIRECTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_sum_direction_class ()))
+
+GfsEventClass * gfs_event_sum_direction_class  (void);
+
+/* GfsEventHarmonic: Header */
+
+typedef struct _GfsEventHarmonic         GfsEventHarmonic;
+
+struct _GfsEventHarmonic {
+  GfsEvent parent;
+
+  GArray * omega;
+  GfsVariable * v, * z, * e, ** A, ** B;
+  gdouble * vsin, * vcos, ** M, ** iM, ** Mn, * x, * a;
+  gchar * Aname, * Bname;
+  gboolean invertible;
+};
+
+#define GFS_EVENT_HARMONIC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventHarmonic,\
+					         gfs_event_harmonic_class ())
+#define GFS_IS_EVENT_HARMONIC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_harmonic_class ()))
+
+GfsEventClass * gfs_event_harmonic_class  (void);
+
+/* GfsEventStop: Header */
+
+typedef struct _GfsEventStop         GfsEventStop;
+
+struct _GfsEventStop {
+  GfsEvent parent;
+
+  GfsVariable * v, * oldv, * diff;
+  gdouble last, max;
+};
+
+#define GFS_EVENT_STOP(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventStop,\
+					         gfs_event_stop_class ())
+#define GFS_IS_EVENT_STOP(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_stop_class ()))
+
+GfsEventClass * gfs_event_stop_class  (void);
+
+/* GfsEventScript: Header */
+
+FILE * gfs_popen (GfsSimulation * sim, 
+		  const char * command, 
+		  const char * type);
+
+typedef struct _GfsEventScript         GfsEventScript;
+
+struct _GfsEventScript {
+  GfsEvent parent;
+
+  gchar * script;
+};
+
+#define GFS_EVENT_SCRIPT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventScript,\
+					         gfs_event_script_class ())
+#define GFS_IS_EVENT_SCRIPT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_script_class ()))
+#define GFS_EVENT_SCRIPT_STOP            64
+
+GfsEventClass * gfs_event_script_class  (void);
+
+/* GfsInitFraction: Header */
+
+typedef struct _GfsInitFraction         GfsInitFraction;
+
+struct _GfsInitFraction {
+  /*< private >*/
+  GfsGenericInit parent;
+
+  GfsVariable * c;
+  GfsGenericSurface * surface;
+};
+
+typedef struct _GfsInitFractionClass    GfsInitFractionClass;
+
+struct _GfsInitFractionClass {
+  /*< private >*/
+  GfsGenericInitClass parent_class;
+
+  /*< public >*/
+};
+
+#define GFS_INIT_FRACTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsInitFraction,\
+					         gfs_init_fraction_class ())
+#define GFS_INIT_FRACTION_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsInitFractionClass,\
+						 gfs_init_fraction_class())
+#define GFS_IS_INIT_FRACTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_init_fraction_class ()))
+
+GfsInitFractionClass * gfs_init_fraction_class  (void);
+
+/* GfsRemoveDroplets: Header */
+
+typedef struct _GfsRemoveDroplets         GfsRemoveDroplets;
+
+struct _GfsRemoveDroplets {
+  /*< private >*/
+  GfsEvent parent;
+  GfsVariable * v;
+
+  /*< public >*/
+  GfsFunction * fc;
+  GfsVariable * c;
+  gint min;
+};
+
+#define GFS_REMOVE_DROPLETS(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsRemoveDroplets,\
+					         gfs_remove_droplets_class ())
+#define GFS_IS_REMOVE_DROPLETS(obj)         (gts_object_is_from_class (obj,\
+						 gfs_remove_droplets_class ()))
+
+GfsEventClass * gfs_remove_droplets_class  (void);
+
+/* GfsRemovePonds: Header */
+
+typedef struct _GfsRemovePonds         GfsRemovePonds;
+
+struct _GfsRemovePonds {
+  /*< private >*/
+  GfsGenericInit parent;
+
+  /*< public >*/
+  gint min;
+};
+
+#define GFS_REMOVE_PONDS(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsRemovePonds,\
+					         gfs_remove_ponds_class ())
+#define GFS_IS_REMOVE_PONDS(obj)         (gts_object_is_from_class (obj,\
+						 gfs_remove_ponds_class ()))
+
+GfsEventClass * gfs_remove_ponds_class  (void);
+
+/* GfsEventFilter: Header */
+
+typedef struct _GfsEventFilter         GfsEventFilter;
+
+struct _GfsEventFilter {
+  /*< private >*/
+  GfsEvent parent;
+  GfsVariable * tmp;
+
+  /*< public >*/
+  GfsVariable * v;
+  gdouble scale;
+};
+
+#define GFS_EVENT_FILTER(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventFilter,\
+					         gfs_event_filter_class ())
+#define GFS_IS_EVENT_FILTER(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_filter_class ()))
+
+GfsEventClass * gfs_event_filter_class  (void);
+
+/* GfsEventList: Header */
+
+typedef struct _GfsEventList         GfsEventList;
+
+struct _GfsEventList {
+  /*< private >*/
+  GfsEvent parent;
+
+  /*< public >*/
+  GtsObjectClass * klass;
+  GtsSListContainer * list;
+};
+
+#define GFS_EVENT_LIST(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsEventList,\
+					         gfs_event_list_class ())
+#define GFS_IS_EVENT_LIST(obj)         (gts_object_is_from_class (obj,\
+						 gfs_event_list_class ()))
+
+GfsEventClass * gfs_event_list_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __EVENT_H__ */
diff --git a/src/fluid.c b/src/fluid.c
new file mode 100644
index 0000000..bb6e8af
--- /dev/null
+++ b/src/fluid.c
@@ -0,0 +1,2754 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+
+#include <stdlib.h>
+
+#include "fluid.h"
+#include "variable.h"
+#include "domain.h"
+#include "solid.h"
+
+/**
+ * gfs_cell_face:
+ * @cell: a #FttCell.
+ * @d: a direction.
+ *
+ * This function is different from ftt_cell_face() because it takes
+ * into account the solid fractions.
+ *
+ * Returns: the face of @cell in direction @d.
+ */
+FttCellFace gfs_cell_face (FttCell * cell,
+			   FttDirection d)
+{
+  FttCellFace f = {cell, NULL, d};
+
+  g_return_val_if_fail (cell != NULL, f);
+
+  if (!GFS_IS_MIXED (cell) || GFS_STATE (cell)->solid->s[d] > 0.)
+    f.neighbor = ftt_cell_neighbor (cell, d);
+  return f;
+}
+
+typedef struct _Gradient Gradient;
+
+/* grad(p) = -a*p(cell) + b*p(neighbor) + c */
+struct _Gradient {
+  gdouble a, b, c;
+};
+
+static gdouble average_neighbor_value (const FttCellFace * face,
+				       guint v,
+				       gdouble * x)
+{
+  /* check for corner refinement violation (topology.fig) */
+  g_assert (ftt_cell_level (face->neighbor) == ftt_cell_level (face->cell));
+  
+  if (FTT_CELL_IS_LEAF (face->neighbor))
+    return GFS_VARIABLE (face->neighbor, v);
+  else {
+    FttCellChildren children;
+    gdouble av = 0., a = 0.;
+    FttDirection od = FTT_OPPOSITE_DIRECTION (face->d);
+    guint i, n;
+    
+    n = ftt_cell_children_direction (face->neighbor, od, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i]) {
+	gdouble w = GFS_IS_MIXED (children.c[i]) ? GFS_STATE (children.c[i])->solid->s[od] : 1.;
+	a += w;
+	av += w*GFS_VARIABLE (children.c[i], v);
+      }
+    if (a > 0.) {
+      *x = 3./4.;
+      return av/a;
+    }
+    else
+      return GFS_VARIABLE (face->cell, v);
+  }
+}
+
+static void average_neighbor_value_stencil (const FttCellFace * face, guint v)
+{
+  /* check for corner refinement violation (topology.fig) */
+  g_assert (ftt_cell_level (face->neighbor) == ftt_cell_level (face->cell));
+  
+  if (FTT_CELL_IS_LEAF (face->neighbor))
+    GFS_VARIABLE (face->neighbor, v) = 1.;
+  else {
+    FttCellChildren children;
+    gdouble a = 0.;
+    guint i, n;
+    
+    n = ftt_cell_children_direction (face->neighbor,
+				     FTT_OPPOSITE_DIRECTION (face->d),
+				     &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i]) {
+	a += 1.;
+	GFS_VARIABLE (children.c[i], v) = 1.;
+      }
+    if (a == 0.)
+      GFS_VARIABLE (face->cell, v) = 1.;
+  }
+}
+
+#if (FTT_2D || FTT_2D3)
+
+/* v = a*v(cell) + b 
+ * 
+ * Second order 1D interpolation.
+ */
+static GfsGradient interpolate_1D2 (FttCell * cell,
+				    FttDirection d,
+				    gdouble x,
+				    guint v)
+{
+  GfsGradient p;
+  FttCellFace f1, f2;
+  gdouble p1 = 0., p2 = 0.;
+  gdouble x1 = 1., x2 = 1.;
+  gdouble a1, a2;
+
+  g_return_val_if_fail (cell != NULL, p);
+  g_return_val_if_fail (!GFS_IS_MIXED (cell), p);
+  
+  f1 = gfs_cell_face (cell, FTT_OPPOSITE_DIRECTION (d));
+  if (f1.neighbor)
+    p1 = average_neighbor_value (&f1, v, &x1);
+  f2 = gfs_cell_face (cell, d);
+  if (f2.neighbor)
+    p2 = average_neighbor_value (&f2, v, &x2);
+
+  a1 = x*(x - x2)/(x1*(x1 + x2));
+  a2 = x*(x + x1)/(x2*(x1 + x2));
+
+  p.a = 1. - a1 - a2;
+  p.b = 0.;
+  if (f1.neighbor)
+    p.b += a1*p1;
+  else
+    p.a += a1;
+  if (f2.neighbor)
+    p.b += a2*p2;
+  else
+    p.a += a2;
+
+  return p;
+}
+
+/* v = a*v(cell) + b 
+ * 
+ * First order 1D interpolation.
+ */
+static GfsGradient interpolate_1D1 (FttCell * cell,
+				    FttDirection d,
+				    gdouble x,
+				    guint v)
+{
+  GfsGradient p;
+  FttCellFace f;
+
+  f = gfs_cell_face (cell, d);
+  if (f.neighbor) {
+    gdouble x2 = 1., p2 = average_neighbor_value (&f, v, &x2);
+    p.a = 1. - x/x2;
+    p.b = p2*x/x2;
+  }
+  else {
+    p.a = 1.;
+    p.b = 0.;
+  }
+
+  return p;
+}
+
+static void interpolate_1D1_stencil (FttCell * cell,
+				     FttDirection d,
+				     guint v)
+{
+  FttCellFace f;
+
+  GFS_VARIABLE (cell, v) = 1.;
+  f = ftt_cell_face (cell, d);
+  if (f.neighbor)
+    average_neighbor_value_stencil (&f, v);
+}
+
+#else /* not FTT_2D */
+
+/* v = a*v(cell) + b 
+ * 
+ * First order 2D interpolation.
+ */
+static GfsGradient interpolate_2D1 (FttCell * cell,
+				    FttDirection d1, FttDirection d2,
+				    gdouble x, gdouble y,
+				    guint v)
+{
+  GfsGradient p;
+  gdouble y1 = 1.;
+  gdouble x2 = 1.;
+  gdouble p1 = 0., p2 = 0.;
+  gdouble a1, a2;
+  FttCellFace f1, f2;
+
+  f1 = gfs_cell_face (cell, d1);
+  if (f1.neighbor)
+    p1 = average_neighbor_value (&f1, v, &y1);
+  f2 = gfs_cell_face (cell, d2);
+  if (f2.neighbor)
+    p2 = average_neighbor_value (&f2, v, &x2);
+
+  a1 = y/y1;
+  a2 = x/x2;
+
+  p.a = 1. - a1 - a2;
+  p.b = 0.;
+  if (f1.neighbor)
+    p.b += a1*p1;
+  else
+    p.a += a1;
+  if (f2.neighbor)
+    p.b += a2*p2;
+  else
+    p.a += a2;
+  
+  return p;
+}
+
+static void interpolate_2D1_stencil (FttCell * cell,
+				     FttDirection d1, FttDirection d2,
+				     guint v)
+{
+  FttCellFace f1, f2;
+
+  GFS_VARIABLE (cell, v) = 1.;
+  f1 = ftt_cell_face (cell, d1);
+  if (f1.neighbor)
+    average_neighbor_value_stencil (&f1, v);
+  f2 = ftt_cell_face (cell, d2);
+  if (f2.neighbor)
+    average_neighbor_value_stencil (&f2, v);
+}
+
+#endif /* not FTT_2D */
+
+#if (FTT_2D || FTT_2D3)
+static gint perpendicular[FTT_NEIGHBORS][FTT_CELLS] = 
+  {{-1,  2, -1,  3},
+   { 2, -1,  3, -1},
+   { 1,  0, -1, -1},
+   {-1, -1,  1,  0}};
+#else  /* FTT_3D */
+static gint perpendicular[FTT_NEIGHBORS][FTT_CELLS][2] = 
+  {{{-1,-1},{2,4},{-1,-1},{3,4},{-1,-1},{2,5},{-1,-1},{3,5}},
+   {{2,4},{-1,-1},{3,4},{-1,-1},{2,5},{-1,-1},{3,5},{-1,-1}},
+   {{4,1},{4,0},{-1,-1},{-1,-1},{5,1},{5,0},{-1,-1},{-1,-1}},
+   {{-1,-1},{-1,-1},{4,1},{4,0},{-1,-1},{-1,-1},{5,1},{5,0}},
+   {{1,2},{0,2},{1,3},{0,3},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
+   {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{1,2},{0,2},{1,3},{0,3}}};
+#endif /* FTT_3D */
+
+static Gradient gradient_fine_coarse (const FttCellFace * face, guint v)
+{
+  Gradient g;
+  GfsGradient p;
+#if (FTT_2D || FTT_2D3)
+  gint dp;
+#else  /* FTT_3D */
+  gint * dp;
+#endif /* FTT_3D */
+
+  g_assert (face != NULL);
+  g_assert (ftt_face_type (face) == FTT_FINE_COARSE);
+
+  dp = perpendicular[face->d][FTT_CELL_ID (face->cell)];
+#if (FTT_2D || FTT_2D3)
+  g_assert (dp >= 0);
+  p = interpolate_1D1 (face->neighbor, dp, 1./4., v);
+#else  /* FTT_3D */
+  g_assert (dp[0] >= 0 && dp[1] >= 0);
+  p = interpolate_2D1 (face->neighbor, dp[0], dp[1], 1./4., 1./4., v);
+#endif /* FTT_3D */
+
+  g.a = 2./3.;
+  g.b = 2.*p.a/3.;
+  g.c = 2.*p.b/3.;
+
+  return g;
+}
+
+#define REFINE_CORNER(cell) {if (cell && FTT_CELL_IS_LEAF (cell) && \
+                              ftt_cell_level (cell) < level - 1) \
+	                    ftt_cell_refine_single (cell, init, data);}
+
+void ftt_cell_refine_corners (FttCell * cell,
+			      FttCellInitFunc init,
+			      gpointer data)
+{
+  FttDirection d;
+  FttCellNeighbors neighbor;
+  guint level;
+
+  g_return_if_fail (cell != NULL);
+
+  level = ftt_cell_level (cell);
+  ftt_cell_neighbors (cell, &neighbor);
+#if FTT_2D3
+  for (d = 0; d < FTT_NEIGHBORS_2D; d++)
+#else /* 2D && 3D */
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+#endif  /* 2D && 3D */
+    if (neighbor.c[d] && ftt_cell_level (neighbor.c[d]) < level) {
+      if (GFS_CELL_IS_BOUNDARY (neighbor.c[d]))
+	ftt_cell_refine_single (neighbor.c[d], init, data);
+      else {
+	FttCell * n;
+#if (FTT_2D || FTT_2D3)
+	gint dp;
+#else  /* FTT_3D */
+	gint * dp;
+#endif /* FTT_3D */
+	
+	dp = perpendicular[d][FTT_CELL_ID (cell)];
+#if (FTT_2D || FTT_2D3)
+	g_assert (dp >= 0);
+	n = ftt_cell_neighbor (neighbor.c[d], dp);
+	REFINE_CORNER (n)
+#else  /* FTT_3D */
+	g_assert (dp[0] >= 0 && dp[1] >= 0);
+	n = ftt_cell_neighbor (neighbor.c[d], dp[0]);
+	REFINE_CORNER (n)
+	n = ftt_cell_neighbor (neighbor.c[d], dp[1]);
+	REFINE_CORNER (n)
+#endif /* FTT_3D */
+      }
+    }
+}
+
+static gdouble neighbor_value (const FttCellFace * face,
+			       guint v,
+			       gdouble * x)
+{
+  GfsGradient vc;
+#if (FTT_2D || FTT_2D3)
+  gint dp;
+#else  /* FTT_3D */
+  gint * dp;
+#endif /* FTT_3D */
+
+  if (ftt_cell_level (face->neighbor) == ftt_cell_level (face->cell))
+    /* neighbor at same level */
+    return average_neighbor_value (face, v, x);
+  else {
+    /* neighbor at coarser level */
+    dp = perpendicular[face->d][FTT_CELL_ID (face->cell)];
+#if (FTT_2D || FTT_2D3)
+    g_assert (dp >= 0);
+    vc = interpolate_1D1 (face->neighbor, dp, 1./4., v);
+#else  /* FTT_3D */
+    g_assert (dp[0] >= 0 && dp[1] >= 0);
+    vc = interpolate_2D1 (face->neighbor, dp[0], dp[1], 1./4., 1./4., v);
+#endif /* FTT_3D */
+    *x = 3./2.;
+    return vc.a*GFS_VARIABLE (face->neighbor, v) + vc.b;
+  }
+}
+
+static void neighbor_value_stencil (const FttCellFace * face, guint v)
+{
+#if (FTT_2D || FTT_2D3)
+  gint dp;
+#else  /* FTT_3D */
+  gint * dp;
+#endif /* FTT_3D */
+
+  if (ftt_cell_level (face->neighbor) == ftt_cell_level (face->cell))
+    /* neighbor at same level */
+    average_neighbor_value_stencil (face, v);
+  else {
+    /* neighbor at coarser level */
+    dp = perpendicular[face->d][FTT_CELL_ID (face->cell)];
+#if (FTT_2D || FTT_2D3)
+    g_assert (dp >= 0);
+    interpolate_1D1_stencil (face->neighbor, dp, v);
+#else  /* FTT_3D */
+    g_assert (dp[0] >= 0 && dp[1] >= 0);
+    interpolate_2D1_stencil (face->neighbor, dp[0], dp[1], v);
+#endif /* FTT_3D */
+    GFS_VARIABLE (face->neighbor, v) = 1.;
+  }
+}
+
+/**
+ * gfs_center_gradient:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable index.
+ *
+ * The gradient is normalized by the size of the cell.
+ *
+ * Returns: the value of the @c component of the gradient of variable @v
+ * at the center of the cell.  
+ */
+gdouble gfs_center_gradient (FttCell * cell,
+			     FttComponent c,
+			     guint v)
+{
+  FttDirection d = 2*c;
+  FttCellFace f1;
+  gdouble v0;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+
+  f1 = gfs_cell_face (cell, FTT_OPPOSITE_DIRECTION (d));
+  v0 = GFS_VARIABLE (cell, v);
+  if (f1.neighbor) {
+    FttCellFace f2 = gfs_cell_face (cell, d);
+    gdouble x1 = 1., v1;
+    
+    v1 = neighbor_value (&f1, v, &x1);
+    if (f2.neighbor) {
+      /* two neighbors: second-order differencing (parabola) */
+      gdouble x2 = 1., v2;
+      
+      v2 = neighbor_value (&f2, v, &x2);
+      return (x1*x1*(v2 - v0) + x2*x2*(v0 - v1))/(x1*x2*(x2 + x1));
+    }
+    else
+      /* one neighbor: first-order differencing */
+      return (v0 - v1)/x1;
+  }
+  else {
+    FttCellFace f2 = gfs_cell_face (cell, d);
+
+    if (f2.neighbor) {
+      gdouble x2 = 1.;
+      
+      /* one neighbor: first-order differencing */
+      return (neighbor_value (&f2, v, &x2) - v0)/x2;
+    }
+  }
+  /* no neighbors */
+  return 0.;
+}
+
+/**
+ * gfs_center_gradient_stencil:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable index.
+ *
+ * Sets to 1. the @v variable of all the cells which would be used if
+ * gfs_center_gradient() was called with identical arguments.
+ */
+void gfs_center_gradient_stencil (FttCell * cell,
+				  FttComponent c,
+				  guint v)
+{
+  FttDirection d = 2*c;
+  FttCellFace f1, f2;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (c < FTT_DIMENSION);
+
+  f1 = ftt_cell_face (cell, FTT_OPPOSITE_DIRECTION (d));
+  if (f1.neighbor == cell) /* periodic */
+    return;
+  if (f1.neighbor) {
+    GFS_VARIABLE (cell, v) = 1.;
+    neighbor_value_stencil (&f1, v);
+  }
+  f2 = ftt_cell_face (cell, d);
+  if (f2.neighbor) {
+    GFS_VARIABLE (cell, v) = 1.;
+    neighbor_value_stencil (&f2, v);
+  }
+}
+
+/**
+ * gfs_center_van_leer_gradient:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable index.
+ *
+ * The gradient is normalized by the size of the cell and is limited
+ * using van Leer's limiter.
+ *
+ * Returns: the value of the @c component of the gradient of variable @v
+ * at the center of the cell.  
+ */
+gdouble gfs_center_van_leer_gradient (FttCell * cell,
+				      FttComponent c,
+				      guint v)
+{
+  FttDirection d = 2*c;
+  FttCellFace f1;
+  
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+
+  f1 = gfs_cell_face (cell, FTT_OPPOSITE_DIRECTION (d));
+  if (f1.neighbor) {
+    FttCellFace f2 = gfs_cell_face (cell, d);
+    
+    if (f2.neighbor) {
+      /* two neighbors: second-order differencing (parabola)
+	 + van Leer limiter */
+      gdouble x1 = 1., x2 = 1., v0, v1, v2;
+      gdouble s0, s1, s2;
+      
+      v0 = GFS_VARIABLE (cell, v);
+      v1 = neighbor_value (&f1, v, &x1);
+      v2 = neighbor_value (&f2, v, &x2);
+
+      s1 = 2.*(v0 - v1);
+      s2 = 2.*(v2 - v0);
+
+      if (s1*s2 <= 0.)
+	return 0.;
+      s0 = (x1*x1*(v2 - v0) + x2*x2*(v0 - v1))/(x1*x2*(x2 + x1));
+      if (ABS (s2) < ABS (s1))
+	s1 = s2;
+      if (ABS (s0) < ABS (s1))
+	return s0;
+      return s1;
+    }
+  }
+  /* only one or no neighbors */
+  return 0.;
+}
+
+static gdouble limiter (gdouble r, gdouble beta)
+{
+  gdouble v1 = MIN (r, beta), v2 = MIN (beta*r, 1.);
+  v1 = MAX (0., v1);
+  return MAX (v1, v2);
+}
+
+/**
+ * gfs_center_minmod_gradient:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable index.
+ *
+ * The gradient is normalized by the size of the cell and is limited
+ * using a minmod limiter.
+ *
+ * Returns: the value of the @c component of the gradient of variable @v
+ * at the center of the cell.  
+ */
+gdouble gfs_center_minmod_gradient (FttCell * cell,
+				    FttComponent c,
+				    guint v)
+{
+  FttDirection d = 2*c;
+  FttCellFace f1;
+  gdouble v0;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+
+  f1 = gfs_cell_face (cell, FTT_OPPOSITE_DIRECTION (d));
+  v0 = GFS_VARIABLE (cell, v);
+  if (f1.neighbor) {
+    FttCellFace f2 = gfs_cell_face (cell, d);
+    if (f2.neighbor) {
+      /* two neighbors */
+      gdouble x1 = 1., v1, x2 = 1., v2;
+      v1 = neighbor_value (&f1, v, &x1);
+      v2 = neighbor_value (&f2, v, &x2);
+
+      gdouble g;
+      if (v0 == v1)
+	g = 0.;
+      else
+	g = limiter ((v2 - v0)*x1/((v0 - v1)*x2), 1.)*(v0 - v1)/x1;
+      return g;
+    }
+  }
+  /* only one or no neighbors */
+  return 0.;
+}
+
+/**
+ * gfs_center_regular_gradient:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable.
+ *
+ * The gradient is normalized by the size of the cell. Only regular
+ * Cartesian stencils are used to compute the gradient.
+ *
+ * Returns: the value of the @c component of the gradient of variable @v
+ * at the center of the cell. 
+ */
+gdouble gfs_center_regular_gradient (FttCell * cell,
+				     FttComponent c,
+				     GfsVariable * v)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  FttCell * n1 = ftt_cell_neighbor (cell, 2*c);
+  guint level = ftt_cell_level (cell);
+  if (n1) {
+    if (ftt_cell_level (n1) < level)
+      return gfs_center_regular_gradient (ftt_cell_parent (cell), c, v)/2.;
+    FttCell * n2 = ftt_cell_neighbor (cell, 2*c + 1);
+    if (n2) {
+      if (ftt_cell_level (n2) < level)
+	return gfs_center_regular_gradient (ftt_cell_parent (cell), c, v)/2.;
+      /* two neighbors: second-order differencing (parabola) */
+      return (GFS_VALUE (n1, v) - GFS_VALUE (n2, v))/2.;
+    }
+    else
+      /* one neighbor: first-order differencing */
+      return GFS_VALUE (n1, v) - GFS_VALUE (cell, v);
+  }
+  else {
+    FttCell * n2 = ftt_cell_neighbor (cell, 2*c + 1);
+    if (n2) {
+      if (ftt_cell_level (n2) < level)
+	return gfs_center_regular_gradient (ftt_cell_parent (cell), c, v)/2.;
+      /* one neighbor: first-order differencing */
+      return GFS_VALUE (cell, v) - GFS_VALUE (n2, v);
+    }
+  }
+  /* no neighbors */
+  return 0.;
+}
+
+/**
+ * gfs_center_regular_2nd_derivative:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable.
+ *
+ * The derivative is normalized by the size of the cell squared. Only
+ * regular Cartesian stencils are used to compute the derivative.
+ *
+ * Returns: the value of the @c component of the 2nd derivative of
+ * variable @v at the center of the cell.
+ */
+gdouble gfs_center_regular_2nd_derivative (FttCell * cell, 
+					   FttComponent c, 
+					   GfsVariable * v)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  FttCell * n1 = ftt_cell_neighbor (cell, 2*c);
+  FttCell * n2 = ftt_cell_neighbor (cell, 2*c + 1);
+  if (n1 && n2) {
+    guint level = ftt_cell_level (cell);
+    if (ftt_cell_level (n1) < level || ftt_cell_level (n2) < level)
+      return gfs_center_regular_2nd_derivative (ftt_cell_parent (cell), c, v)/4.;
+    return GFS_VALUE (n1, v) - 2.*GFS_VALUE (cell, v) + GFS_VALUE (n2, v);
+  }
+  /* one or no neighbors */
+  return 0.;
+}
+
+/**
+ * gfs_face_gradient:
+ * @face: a #FttCellFace.
+ * @g: the #GfsGradient.
+ * @v: a #GfsVariable index.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ *
+ * Set the value of @g as the gradient of variable @v on the
+ * @face. The value returned is second order accurate in space and
+ * conservative, in the sense that values at a coarse/fine cell
+ * boundary are consistent.
+ *
+ * The value of the gradient (normalised by the size of @face->cell)
+ * is given by: @g->b - @g->a*GFS_VARIABLE (@face->cell, @v).
+ */
+void gfs_face_gradient (const FttCellFace * face,
+			GfsGradient * g,
+			guint v,
+			gint max_level)
+{
+  guint level;
+
+  g_return_if_fail (face != NULL);
+
+  g->a = g->b = 0.;
+  if (face->neighbor == NULL || GFS_FACE_FRACTION (face) == 0.)
+    return;
+
+  level = ftt_cell_level (face->cell);
+  if (ftt_cell_level (face->neighbor) < level) {
+    /* neighbor is at a shallower level */
+    Gradient gcf;
+
+    gcf = gradient_fine_coarse (face, v);
+    g->a = gcf.a;
+    g->b = gcf.b*GFS_VARIABLE (face->neighbor, v) + gcf.c;
+  }
+  else {
+    if (level == max_level || FTT_CELL_IS_LEAF (face->neighbor)) {
+      /* neighbor is at the same level */
+      g->a = 1.;
+      g->b = GFS_VARIABLE (face->neighbor, v);
+    }
+    else {
+      /* neighbor is at a deeper level */
+      FttCellChildren children;
+      FttCellFace f;
+      guint i, n;
+      gdouble s;
+      
+      f.d = FTT_OPPOSITE_DIRECTION (face->d);
+      n = ftt_cell_children_direction (face->neighbor, f.d, &children);
+      f.neighbor = face->cell;
+      for (i = 0; i < n; i++)
+	if ((f.cell = children.c[i])) {
+	  Gradient gcf;
+	  gcf = gradient_fine_coarse (&f, v);
+	  s = GFS_FACE_FRACTION (&f);
+	  g->a += s*gcf.b;
+	  g->b += s*(gcf.a*GFS_VARIABLE (f.cell, v) - gcf.c);
+	}
+      s = GFS_FACE_FRACTION (face)*n/2.;
+      g->a /= s;
+      g->b /= s;
+    }
+  }
+}
+
+static void face_weighted_gradient (const FttCellFace * face,
+				    GfsGradient * g,
+				    guint v,
+				    gint max_level,
+				    guint dimension)
+{
+  guint level;
+
+  g_return_if_fail (face != NULL);
+
+  g->a = g->b = 0.;
+  if (face->neighbor == NULL)
+    return;
+
+  level = ftt_cell_level (face->cell);
+  if (ftt_cell_level (face->neighbor) < level) {
+    /* neighbor is at a shallower level */
+    Gradient gcf;
+    gdouble w = GFS_STATE (face->cell)->f[face->d].v;
+
+    gcf = gradient_fine_coarse (face, v);
+    g->a = w*gcf.a;
+    g->b = w*(gcf.b*GFS_VARIABLE (face->neighbor, v) + gcf.c);
+  }
+  else {
+    if (level == max_level || FTT_CELL_IS_LEAF (face->neighbor)) {
+      /* neighbor is at the same level */
+      gdouble w = GFS_STATE (face->cell)->f[face->d].v;
+
+      g->a = w;
+      g->b = w*GFS_VARIABLE (face->neighbor, v);
+    }
+    else {
+      /* neighbor is at a deeper level */
+      FttCellChildren children;
+      FttCellFace f;
+      guint i, n;
+      
+      f.d = FTT_OPPOSITE_DIRECTION (face->d);
+      n = ftt_cell_children_direction (face->neighbor, f.d, &children);
+      f.neighbor = face->cell;
+      for (i = 0; i < n; i++) 
+	if ((f.cell = children.c[i])) {
+	  Gradient gcf;
+	  gdouble w = GFS_STATE (f.cell)->f[f.d].v;
+	
+	  gcf = gradient_fine_coarse (&f, v);
+	  g->a += w*gcf.b;
+	  g->b += w*(gcf.a*GFS_VARIABLE (f.cell, v) - gcf.c);
+	}
+      if (dimension > 2) {
+	/* fixme??? */
+	g->a /= n/2.;
+	g->b /= n/2.;
+      }
+    }
+  }
+}
+
+/**
+ * gfs_face_weighted_gradient:
+ * @face: a #FttCellFace.
+ * @g: the #GfsGradient.
+ * @v: a #GfsVariable index.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ *
+ * Set the value of @g as the gradient of variable @v on the @face
+ * weighted by the value of the @v field of the face state vector of the
+ * corresponding cell. The value returned is second order accurate in
+ * space and conservative, in the sense that values at a coarse/fine
+ * cell boundary are consistent.  
+ */
+void gfs_face_weighted_gradient (const FttCellFace * face,
+				 GfsGradient * g,
+				 guint v,
+				 gint max_level)
+{
+  face_weighted_gradient (face, g, v, max_level, FTT_DIMENSION);
+}
+
+void gfs_face_weighted_gradient_2D (const FttCellFace * face,
+				    GfsGradient * g,
+				    guint v,
+				    gint max_level)
+{
+  face_weighted_gradient (face, g, v, max_level, 2);
+}
+
+static void fullest_directions (const FttCellFace * face,
+				FttDirection d[FTT_DIMENSION])
+{
+  FttComponent c = face->d/2, i;
+  FttCell * mixed = GFS_IS_MIXED (face->cell) ? face->cell : face->neighbor;
+  GfsSolidVector * s = GFS_STATE (mixed)->solid;
+
+  d[0] = face->d;
+  for (i = 1; i < FTT_DIMENSION; i++) {
+    guint cp = (c + i) % FTT_DIMENSION;
+    d[i] = s->s[2*cp] > s->s[2*cp + 1] ? 2*cp : 2*cp + 1;
+  }
+}
+
+static FttCell * cell_corner_neighbor1 (FttCell * cell,
+					FttDirection * d,
+					gint max_level)
+{
+  if (!cell)
+    return NULL;
+  FttCell * neighbor = ftt_cell_neighbor (cell, d[0]);
+  if (!neighbor)
+    return NULL;
+  else {
+    guint level = ftt_cell_level (cell);
+    if (ftt_cell_level (neighbor) < level)
+      /* neighbor is at a shallower level */
+      return neighbor;
+    else {
+      if (level == max_level || FTT_CELL_IS_LEAF (neighbor))
+	/* neighbor is at the same level */
+	return neighbor;
+      else {
+	/* neighbor is at a deeper level */
+	guint i;
+	FttDirection d1[FTT_DIMENSION];
+	d1[0] = FTT_OPPOSITE_DIRECTION (d[0]);
+	for (i = 1; i < FTT_DIMENSION; i++)
+	  d1[i] = d[i];
+	return ftt_cell_child_corner (neighbor, d1);
+      }
+    }
+  }
+}
+
+#if FTT_2D
+# define N_CELLS 4
+#else  /* 2D3 and 3D */
+# define N_CELLS 8
+#endif /* 2D3 and 3D */
+
+static gboolean inverse (gdouble mi[N_CELLS - 1][N_CELLS - 1])
+{
+#if FTT_2D
+  gdouble m[N_CELLS - 1][N_CELLS - 1], det;
+  guint i, j;
+  
+  for (i = 0; i < N_CELLS - 1; i++)
+    for (j = 0; j < N_CELLS - 1; j++)
+      m[i][j] = mi[i][j];
+  
+  det = (m[0][0]*(m[1][1]*m[2][2] - m[2][1]*m[1][2]) -
+	 m[0][1]*(m[1][0]*m[2][2] - m[2][0]*m[1][2]) +
+	 m[0][2]*(m[1][0]*m[2][1] - m[2][0]*m[1][1]));
+  if (det == 0.)
+    return FALSE;
+  
+  mi[0][0] = (m[1][1]*m[2][2] - m[1][2]*m[2][1])/det; 
+  mi[0][1] = (m[2][1]*m[0][2] - m[0][1]*m[2][2])/det;
+  mi[0][2] = (m[0][1]*m[1][2] - m[1][1]*m[0][2])/det; 
+  mi[1][0] = (m[1][2]*m[2][0] - m[1][0]*m[2][2])/det; 
+  mi[1][1] = (m[0][0]*m[2][2] - m[2][0]*m[0][2])/det; 
+  mi[1][2] = (m[1][0]*m[0][2] - m[0][0]*m[1][2])/det; 
+  mi[2][0] = (m[1][0]*m[2][1] - m[2][0]*m[1][1])/det; 
+  mi[2][1] = (m[2][0]*m[0][1] - m[0][0]*m[2][1])/det; 
+  mi[2][2] = (m[0][0]*m[1][1] - m[0][1]*m[1][0])/det; 
+#else /* 3D */
+  gint indxc[N_CELLS - 1], indxr[N_CELLS - 1], ipiv[N_CELLS - 1];
+  gint i, icol = 0, irow = 0, j, k, l, ll;
+  gdouble big, dum, pivinv, temp;
+  
+#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
+
+  for (j = 0; j < N_CELLS - 1; j++) 
+    ipiv[j] = -1;
+
+  for (i = 0; i < N_CELLS - 1; i++) {
+    big = 0.0;
+    for (j = 0; j < N_CELLS - 1; j++)
+      if (ipiv[j] != 0)
+	for (k = 0; k < N_CELLS - 1; k++) {
+	  if (ipiv[k] == -1) {
+	    if (fabs (mi[j][k]) >= big) {
+	      big = fabs (mi[j][k]);
+	      irow = j;
+	      icol = k;
+	    }
+	  }
+	}
+    ipiv[icol]++;
+    if (irow != icol)
+      for (l = 0; l < N_CELLS - 1; l++) 
+	SWAP (mi[irow][l], mi[icol][l]);
+    indxr[i] = irow;
+    indxc[i] = icol;
+    if (mi[icol][icol] == 0.)
+      return FALSE;
+    pivinv = 1.0/mi[icol][icol];
+    mi[icol][icol] = 1.0;
+    for (l = 0; l < N_CELLS - 1; l++) mi[icol][l] *= pivinv;
+    for (ll = 0; ll < N_CELLS - 1; ll++)
+      if (ll != icol) {
+	dum = mi[ll][icol];
+	mi[ll][icol] = 0.0;
+	for (l = 0; l < N_CELLS - 1; l++)
+	  mi[ll][l] -= mi[icol][l]*dum;
+      }
+  }
+  for (l = N_CELLS - 1 - 1; l >= 0; l--) {
+    if (indxr[l] != indxc[l])
+      for (k = 0; k < N_CELLS - 1; k++)
+	SWAP (mi[k][indxr[l]], mi[k][indxc[l]]);
+  }
+#endif /* 3D */
+  return TRUE;
+}
+
+#if (!FTT_2D)
+static void draw_cell (FttCell * cell, gdouble r, gdouble g, gdouble b,
+		       const gchar * name)
+{
+  FttVector p;
+  gdouble size = ftt_cell_size (cell)/2.;
+
+  ftt_cell_pos (cell, &p);
+  fprintf (stderr,
+	   "(geometry \"%s\" = OFF 8 6 12\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "4 3 2 1 0 %g %g %g\n"
+	   "4 4 5 6 7 %g %g %g\n"
+	   "4 2 3 7 6 %g %g %g\n"
+	   "4 0 1 5 4 %g %g %g\n"
+	   "4 0 4 7 3 %g %g %g\n"
+	   "4 1 2 6 5 %g %g %g\n"
+	   ")\n",
+	   name,
+	   p.x - size, p.y - size, p.z - size,
+	   p.x + size, p.y - size, p.z - size,
+	   p.x + size, p.y + size, p.z - size,
+	   p.x - size, p.y + size, p.z - size,
+	   p.x - size, p.y - size, p.z + size,
+	   p.x + size, p.y - size, p.z + size,
+	   p.x + size, p.y + size, p.z + size,
+	   p.x - size, p.y + size, p.z + size,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b);
+  gfs_cell_cm (cell, &p);
+  size /= 8.;
+  fprintf (stderr,
+	   "(geometry \"cm %s\" = OFF 8 6 12\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "4 3 2 1 0 %g %g %g\n"
+	   "4 4 5 6 7 %g %g %g\n"
+	   "4 2 3 7 6 %g %g %g\n"
+	   "4 0 1 5 4 %g %g %g\n"
+	   "4 0 4 7 3 %g %g %g\n"
+	   "4 1 2 6 5 %g %g %g\n"
+	   ")\n",
+	   name,
+	   p.x - size, p.y - size, p.z - size,
+	   p.x + size, p.y - size, p.z - size,
+	   p.x + size, p.y + size, p.z - size,
+	   p.x - size, p.y + size, p.z - size,
+	   p.x - size, p.y - size, p.z + size,
+	   p.x + size, p.y - size, p.z + size,
+	   p.x + size, p.y + size, p.z + size,
+	   p.x - size, p.y + size, p.z + size,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b,
+	   r, g, b);
+}
+
+static void output_error_mesh (FttCell ** n)
+{
+  draw_cell (n[0], 0., 0., 0., "n0");
+  draw_cell (n[1], 0.5, 0., 0., "n1");
+  draw_cell (n[2], 0., 0.5, 0., "n2");
+  draw_cell (n[3], 0., 0., 0.5, "n3");
+  draw_cell (n[4], 1., 1., 1., "n4");
+  draw_cell (n[5], 1., 0., 0., "n5");
+  draw_cell (n[6], 0., 1., 0., "n6");
+  draw_cell (n[7], 0., 0., 1., "n7");
+  g_assert_not_reached ();
+}
+#endif /* 3D */
+
+static gboolean face_bilinear (const FttCellFace * face,
+			       FttCell ** n,
+			       FttVector * o,
+			       void (*cell_pos) (const FttCell *, FttVector *),
+			       gint max_level,
+			       gdouble m[N_CELLS - 1][N_CELLS - 1])
+{
+  FttDirection d[3], d1[3];
+  guint i;
+  gdouble size = ftt_cell_size (face->cell);
+
+  fullest_directions (face, d);
+  n[0] = face->cell; n[1] = face->neighbor;
+  d1[0] = d[1]; d1[1] = d[0]; d1[2] = d[2];
+  if ((n[2] = cell_corner_neighbor1 (n[0], d1, max_level)) == NULL)
+    return FALSE;
+  d1[1] = FTT_OPPOSITE_DIRECTION (d[0]);
+  if ((n[3] = cell_corner_neighbor1 (n[1], d1, max_level)) == NULL)
+    return FALSE;
+  if (n[3] == n[2]) {
+    d1[0] = d[0]; d1[1] = FTT_OPPOSITE_DIRECTION (d[1]);
+    if ((n[3] = cell_corner_neighbor1 (n[2], d1, max_level)) == NULL)
+      return FALSE;
+  }
+
+#if FTT_2D
+  for (i = 0; i < 3; i++) {
+    FttVector cm;
+    guint j;
+
+    (*cell_pos) (n[i + 1], &cm);
+
+    for (j = 0; j < FTT_DIMENSION; j++) {
+      (&cm.x)[j] -= (&o->x)[j];
+      (&cm.x)[j] /= size;
+      g_assert (fabs ((&cm.x)[j]) <= 4.);
+    }
+
+    m[i][0] = cm.x;
+    m[i][1] = cm.y; 
+    m[i][2] = cm.x*cm.y;
+  }
+  g_assert (inverse (m));
+#else /* 3D */
+  d1[0] = d[2]; d1[1] = d[0]; d1[2] = d[1];
+  if ((n[4] = cell_corner_neighbor1 (n[0], d1, max_level)) == NULL)
+    return FALSE;
+  d1[1] = FTT_OPPOSITE_DIRECTION (d[0]);
+  if ((n[5] = cell_corner_neighbor1 (n[1], d1, max_level)) == NULL)
+    return FALSE;
+  if (n[5] == n[4]) {
+    d1[0] = d[0]; d1[1] = d[1]; d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+    if ((n[5] = cell_corner_neighbor1 (n[4], d1, max_level)) == NULL)
+      return FALSE;
+  }
+  d1[0] = d[2]; d1[1] = d[0]; d1[2] = FTT_OPPOSITE_DIRECTION (d[1]);
+  if ((n[6] = cell_corner_neighbor1 (n[2], d1, max_level)) == NULL)
+    return FALSE;
+  if (n[6] == n[4]) {
+    d1[0] = d[1]; d1[1] = d[0]; d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+    if ((n[6] = cell_corner_neighbor1 (n[4], d1, max_level)) == NULL)
+      return FALSE;
+  }
+  d1[0] = d[2]; d1[1] = FTT_OPPOSITE_DIRECTION (d[0]); d1[2] = FTT_OPPOSITE_DIRECTION (d[1]);
+  if ((n[7] = cell_corner_neighbor1 (n[3], d1, max_level)) == NULL)
+    return FALSE;
+  if (n[7] == n[4] || n[7] == n[5]) {
+    d1[0] = d[1]; d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+    if ((n[7] = cell_corner_neighbor1 (n[5], d1, max_level)) == NULL)
+      return FALSE;
+  }
+  if (n[7] == n[6]) {
+    d1[0] = d[0]; d1[1] = FTT_OPPOSITE_DIRECTION (d[1]); d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+    if ((n[7] = cell_corner_neighbor1 (n[6], d1, max_level)) == NULL)
+      return FALSE;
+  }
+
+  for (i = 0; i < 7; i++) {
+    FttVector cm;
+    guint j;
+
+    for (j = i + 1; j < 7; j++)
+      if (n[i + 1] == n[j + 1])
+	output_error_mesh (n);
+
+    (*cell_pos) (n[i + 1], &cm);
+
+    for (j = 0; j < FTT_DIMENSION; j++) {
+      (&cm.x)[j] -= (&o->x)[j];
+      (&cm.x)[j] /= size;
+      if (fabs ((&cm.x)[j]) > 4.)
+	output_error_mesh (n);
+    }
+
+    m[i][0] = cm.x;
+    m[i][1] = cm.y; 
+    m[i][2] = cm.z;
+    m[i][3] = cm.x*cm.y;
+    m[i][4] = cm.x*cm.z;
+    m[i][5] = cm.y*cm.z;
+    m[i][6] = cm.x*cm.y*cm.z;
+  }
+  if (!inverse (m))
+    output_error_mesh (n);
+#endif /* 3D */
+
+  return TRUE;
+}
+
+/* grad(v) = -a*v(cell) + b*v(neighbor) + c */
+static gboolean mixed_face_gradient (const FttCellFace * face,
+				     Gradient * g,
+				     guint v,
+				     gint max_level)
+{
+  FttCell * n[N_CELLS];
+  gdouble m[N_CELLS - 1][N_CELLS - 1];
+  FttVector o, cm;
+  FttComponent c = face->d/2;
+  gdouble h = ftt_cell_size (face->cell);
+
+  gfs_cell_cm (face->cell, &o);
+  if (!face_bilinear (face, n, &o, gfs_cell_cm, max_level, m))
+    return FALSE;
+
+  gfs_face_ca (face, &cm);
+
+#if FTT_2D
+  {
+    FttComponent cp = FTT_ORTHOGONAL_COMPONENT (c);
+    gdouble vp;
+    
+    vp = ((&cm.x)[cp] - (&o.x)[cp])/h;
+    g->a = ((m[c][0] + m[2][0]*vp) +
+	    (m[c][1] + m[2][1]*vp) +
+	    (m[c][2] + m[2][2]*vp));
+    g->b = m[c][0] + m[2][0]*vp;
+    g->c = ((m[c][1] + m[2][1]*vp)*GFS_VARIABLE (n[2], v) +
+	    (m[c][2] + m[2][2]*vp)*GFS_VARIABLE (n[3], v));
+  }
+#else /* 3D */
+  {
+    guint j;
+
+    cm.x = (cm.x - o.x)/h;
+    cm.y = (cm.y - o.y)/h;
+    cm.z = (cm.z - o.z)/h;
+    g->c = 0.;
+    
+    switch (c) {
+    case FTT_X:
+      g->a = g->b = m[0][0] + cm.y*m[3][0] + cm.z*m[4][0] + cm.y*cm.z*m[6][0];
+      for (j = 1; j < N_CELLS - 1; j++) {
+	gdouble a = m[0][j] + cm.y*m[3][j] + cm.z*m[4][j] + cm.y*cm.z*m[6][j];
+	g->a += a;
+	g->c += a*GFS_VARIABLE (n[j+1], v);
+      }
+      break;
+    case FTT_Y:
+      g->a = g->b = m[1][0] + cm.x*m[3][0] + cm.z*m[5][0] + cm.x*cm.z*m[6][0];
+      for (j = 1; j < N_CELLS - 1; j++) {
+	gdouble a = m[1][j] + cm.x*m[3][j] + cm.z*m[5][j] + cm.x*cm.z*m[6][j];
+	g->a += a;
+	g->c += a*GFS_VARIABLE (n[j+1], v);
+      }
+      break;
+    case FTT_Z:
+      g->a = g->b = m[2][0] + cm.x*m[4][0] + cm.y*m[5][0] + cm.x*cm.y*m[6][0];
+      for (j = 1; j < N_CELLS - 1; j++) {
+	gdouble a = m[2][j] + cm.x*m[4][j] + cm.y*m[5][j] + cm.x*cm.y*m[6][j];
+	g->a += a;
+	g->c += a*GFS_VARIABLE (n[j+1], v);
+      }
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+  }
+#endif /* 3D */
+
+  if (!FTT_FACE_DIRECT (face)) {
+    g->a = - g->a;
+    g->b = - g->b;
+    g->c = - g->c;
+  }
+
+  return TRUE;
+}
+
+/**
+ * gfs_face_gradient_flux:
+ * @face: a #FttCellFace.
+ * @g: the #GfsGradient.
+ * @v: a #GfsVariable index.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ *
+ * Set the value of @g as the gradient of variable @v on the @face
+ * weighted by the value of the @v field of the face state vector of
+ * the corresponding cell. Variable @v is defined at the center of
+ * mass of its cell. Linear interpolation is used to evaluate the
+ * gradient in the vicinity of cut cells.
+ */
+void gfs_face_gradient_flux (const FttCellFace * face,
+			     GfsGradient * g,
+			     guint v,
+			     gint max_level)
+{
+  guint level;
+  Gradient gcf;
+  gdouble w;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (g != NULL);
+
+  g->a = g->b = 0.;
+  if (face->neighbor == NULL || (w = GFS_STATE (face->cell)->f[face->d].v) == 0.)
+    return;
+
+  level = ftt_cell_level (face->cell);
+  if (ftt_cell_level (face->neighbor) < level) {
+    /* neighbor is at a shallower level */
+    if (GFS_IS_MIXED (face->cell) || GFS_IS_MIXED (face->neighbor)) {
+      if (!mixed_face_gradient (face, &gcf, v, max_level))
+	gcf = gradient_fine_coarse (face, v);
+    }
+    else
+      gcf = gradient_fine_coarse (face, v);
+    g->a = w*gcf.a;
+    g->b = w*(gcf.b*GFS_VARIABLE (face->neighbor, v) + gcf.c);
+  }
+  else {
+    if (level == max_level || FTT_CELL_IS_LEAF (face->neighbor)) {
+      /* neighbor is at the same level */
+      if (!GFS_IS_MIXED (face->cell) && !GFS_IS_MIXED (face->neighbor)) {
+	g->a = w;
+	g->b = w*GFS_VARIABLE (face->neighbor, v);
+      }
+      else if (mixed_face_gradient (face, &gcf, v, max_level)) {
+	g->a = w*gcf.a;
+	g->b = w*(gcf.b*GFS_VARIABLE (face->neighbor, v) + gcf.c);
+      }
+      else {
+	g->a = w;
+	g->b = w*GFS_VARIABLE (face->neighbor, v);
+      }
+    }
+    else {
+      /* neighbor is at a deeper level */
+      FttCellChildren children;
+      FttCellFace f;
+      guint i, n;
+      
+      f.d = FTT_OPPOSITE_DIRECTION (face->d);
+      n = ftt_cell_children_direction (face->neighbor, f.d, &children);
+      f.neighbor = face->cell;
+      for (i = 0; i < n; i++) 
+	if ((f.cell = children.c[i])) {
+	  w = GFS_STATE (f.cell)->f[f.d].v;
+	  if (GFS_IS_MIXED (f.cell) || GFS_IS_MIXED (f.neighbor)) {
+	    if (!mixed_face_gradient (&f, &gcf, v, max_level))
+	      gcf = gradient_fine_coarse (&f, v);
+	  }
+	  else
+	    gcf = gradient_fine_coarse (&f, v);
+	  g->a += w*gcf.b;
+	  g->b += w*(gcf.a*GFS_VARIABLE (f.cell, v) - gcf.c);
+	}
+    }
+  }
+}
+
+static gboolean cell_bilinear (FttCell * cell,
+			       FttCell ** n,
+			       FttVector * o,
+			       void (*cell_pos) (const FttCell *, FttVector *),
+			       gint max_level,
+			       gdouble m[N_CELLS - 1][N_CELLS - 1])
+{
+  GfsSolidVector * s = GFS_STATE (cell)->solid;  
+  FttCellFace f;
+  FttDirection d[FTT_DIMENSION];
+  FttComponent c;
+
+  if ((s->s[FTT_RIGHT] == 0. && s->s[FTT_LEFT] == 0.) ||
+      (s->s[FTT_RIGHT] == 1. && s->s[FTT_LEFT] == 1.))
+    return FALSE;
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    d[c] = s->s[2*c] > s->s[2*c + 1] ? 2*c : 2*c + 1;
+  f.cell = cell;
+  f.d = d[0];
+  f.neighbor = cell_corner_neighbor1 (cell, d, max_level);
+
+  return face_bilinear (&f, n, o, cell_pos, max_level, m);
+}
+
+/**
+ * gfs_cell_dirichlet_gradient:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable index.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ * @v0: the Dirichlet value on the boundary.
+ * @grad: a #FttVector.
+ *
+ * Fills @grad with components of the gradient of variable @v
+ * interpolated at the center of area of the solid boundary contained
+ * in @cell. The gradient is scaled by the size of the cell.
+ */
+void gfs_cell_dirichlet_gradient (FttCell * cell,
+				  guint v,
+				  gint max_level,
+				  gdouble v0,
+				  FttVector * grad)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (grad != NULL);
+
+  if (!GFS_IS_MIXED (cell))
+    return;
+  else {
+    FttCell * n[N_CELLS];
+    gdouble m[N_CELLS - 1][N_CELLS - 1];
+    guint i, c;
+
+    grad->x = grad->y = grad->z = 0.;
+    if (!cell_bilinear (cell, n, &GFS_STATE (cell)->solid->ca, 
+			gfs_cell_cm, max_level, m))
+      return;
+
+    for (i = 0; i < N_CELLS - 1; i++)
+      for (c = 0; c < FTT_DIMENSION; c++)
+	(&grad->x)[c] += m[c][i]*(GFS_VARIABLE (n[i + 1], v) - v0);
+  }
+}
+
+/**
+ * gfs_mixed_cell_gradient:
+ * @cell: a mixed #FttCell.
+ * @v: a #GfsVariable.
+ * @g: the gradient.
+ *
+ * Fills @g with the components of the gradient of @v at the center of
+ * mass of @cell.
+ *
+ * The gradient is normalized by the size of the cell.
+ */
+void gfs_mixed_cell_gradient (FttCell * cell,
+			      GfsVariable * v,
+			      FttVector * g)
+{
+  FttCell * n[N_CELLS];
+  gdouble m[N_CELLS - 1][N_CELLS - 1];
+  gdouble v0, h;
+  FttVector * o, cm;
+  guint i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (GFS_IS_MIXED (cell));
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (g != NULL);
+
+  g->x = g->y = g->z = 0.;
+
+  o = &GFS_STATE (cell)->solid->cm;
+  v0 = GFS_VARIABLE (cell, v->i);
+  cm = *o;
+
+  if (v->surface_bc) {
+    (* GFS_SURFACE_GENERIC_BC_CLASS (GTS_OBJECT (v->surface_bc)->klass)->bc) (cell, v->surface_bc);
+    if (((cell)->flags & GFS_FLAG_DIRICHLET) != 0) {
+      o = &GFS_STATE (cell)->solid->ca;
+      v0 = GFS_STATE (cell)->solid->fv;
+    }
+  }
+  g_assert (cell_bilinear (cell, n, o, gfs_cell_cm, -1, m));
+  
+  h = ftt_cell_size (cell);
+  cm.x = (cm.x - o->x)/h;
+  cm.y = (cm.y - o->y)/h;
+  cm.z = (cm.z - o->z)/h;
+  for (i = 0; i < N_CELLS - 1; i++) {
+    gdouble val = GFS_VARIABLE (n[i + 1], v->i) - v0;
+#if FTT_2D
+    g->x += (m[0][i] + m[2][i]*cm.y)*val;
+    g->y += (m[1][i] + m[2][i]*cm.x)*val;
+#else /* 3D */
+    g->x += (m[0][i] + m[3][i]*cm.y + m[4][i]*cm.z + m[6][i]*cm.y*cm.z)*val;
+    g->y += (m[1][i] + m[3][i]*cm.x + m[5][i]*cm.z + m[6][i]*cm.x*cm.z)*val;
+    g->z += (m[2][i] + m[4][i]*cm.x + m[5][i]*cm.y + m[6][i]*cm.x*cm.y)*val;
+#endif /* 3D */
+  }
+}
+
+/**
+ * gfs_mixed_cell_interpolate:
+ * @cell: a mixed #FttCell.
+ * @p: a #FttVector.
+ * @v: a #GfsVariable.
+ *
+ * Returns: the value of variable @v interpolated at position @p within @cell.
+ */
+gdouble gfs_mixed_cell_interpolate (FttCell * cell,
+				    FttVector p,
+				    GfsVariable * v)
+{
+  FttCell * n[N_CELLS];
+  gdouble m[N_CELLS - 1][N_CELLS - 1], a[N_CELLS - 1];
+  gdouble v0, h;
+  FttVector * o;
+  guint i, j;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (GFS_IS_MIXED (cell), 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  o = &GFS_STATE (cell)->solid->cm;
+  v0 = GFS_VALUE (cell, v);
+
+  if (v->surface_bc) {
+    (* GFS_SURFACE_GENERIC_BC_CLASS (GTS_OBJECT (v->surface_bc)->klass)->bc) (cell, v->surface_bc);
+    if (((cell)->flags & GFS_FLAG_DIRICHLET) != 0) {
+      o = &GFS_STATE (cell)->solid->ca;
+      v0 = GFS_STATE (cell)->solid->fv;
+    }
+  }
+  g_assert (cell_bilinear (cell, n, o, gfs_cell_cm, -1, m));
+
+  for (i = 0; i < N_CELLS - 1; i++) {
+    a[i] = 0.;
+    for (j = 0; j < N_CELLS - 1; j++)
+      a[i] += m[i][j]*(GFS_VALUE (n[j + 1], v) - v0);
+  }
+  
+  h = ftt_cell_size (cell);
+  p.x = (p.x - o->x)/h;
+  p.y = (p.y - o->y)/h;
+#if FTT_2D
+  return a[0]*p.x + a[1]*p.y + a[2]*p.x*p.y + v0;
+#else /* 3D */
+  p.z = (p.z - o->z)/h;
+  return (a[0]*p.x + a[1]*p.y + a[2]*p.z + 
+	  a[3]*p.x*p.y + a[4]*p.x*p.z + a[5]*p.y*p.z + 
+	  a[6]*p.x*p.y*p.z + v0);
+#endif /* 3D */
+}
+
+/**
+ * gfs_cell_dirichlet_gradient_flux:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable index.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ * @v0: the Dirichlet value on the boundary.
+ *
+ * Returns: the flux of the gradient of variable @v through the solid
+ * boundary contained in @cell.
+ */
+gdouble gfs_cell_dirichlet_gradient_flux (FttCell * cell,
+					  guint v,
+					  gint max_level,
+					  gdouble v0)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  if (!GFS_IS_MIXED (cell))
+    return 0.;
+  else {
+    GfsSolidVector * s = GFS_STATE (cell)->solid;
+    FttVector g;
+    
+    gfs_cell_dirichlet_gradient (cell, v, max_level, v0, &g);
+
+    return (g.x*(s->s[1] - s->s[0]) + g.y*(s->s[3] - s->s[2])
+#if (!FTT_2D)
+	    + g.z*(s->s[5] - s->s[4])
+#endif
+	    )*s->v;
+  }
+}
+
+/**
+ * gfs_cell_dirichlet_value:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ *
+ * Returns: the value of variable @v interpolated at the center of
+ * area of the solid boundary contained in @cell.
+ */
+gdouble gfs_cell_dirichlet_value (FttCell * cell,
+				  GfsVariable * v,
+				  gint max_level)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  if (!GFS_IS_MIXED (cell))
+    return 0.;
+  else {
+    FttCell * n[N_CELLS];
+    FttVector p;
+    gdouble m[N_CELLS - 1][N_CELLS - 1], a[N_CELLS - 1];
+    GfsSolidVector * s = GFS_STATE (cell)->solid;
+    gdouble v0, size = ftt_cell_size (cell);
+    void (* cell_pos) (const FttCell *, FttVector *) = v->centered ? ftt_cell_pos : gfs_cell_cm;
+    guint i, j;
+
+    (*cell_pos) (cell, &p);
+    if (!cell_bilinear (cell, n, &p, cell_pos, max_level, m))
+      return 0.;
+
+    v0 = GFS_VARIABLE (cell, v->i);
+    for (i = 0; i < N_CELLS - 1; i++) {
+      a[i] = 0.;
+      for (j = 0; j < N_CELLS - 1; j++)
+	a[i] += m[i][j]*(GFS_VARIABLE (n[j + 1], v->i) - v0);
+    }
+    p.x = (s->ca.x - p.x)/size;
+    p.y = (s->ca.y - p.y)/size;
+#if FTT_2D
+    return (a[0]*p.x + a[1]*p.y + a[2]*p.x*p.y + v0);
+#else /* 3D */
+    p.z = (s->ca.z - p.z)/size;
+    return (a[0]*p.x + a[1]*p.y + a[2]*p.z + 
+	    a[3]*p.x*p.y + a[4]*p.x*p.z + a[5]*p.y*p.z + 
+	    a[6]*p.x*p.y*p.z + v0);
+#endif /* 3D */
+  }
+}
+
+/**
+ * gfs_shear_strain_rate_tensor:
+ * @cell: a #FttCell.
+ * @u: the velocity.
+ * @t: the shear strain rate tensor t[i][j] = (d_iu_j+d_ju_i)/2.
+ *
+ * Fills @t with the shear strain rate tensor at the center of mass of
+ * @cell, normalised by the size of the cell.
+ */
+void gfs_shear_strain_rate_tensor (FttCell * cell, 
+				   GfsVariable ** u,
+				   gdouble t[FTT_DIMENSION][FTT_DIMENSION])
+{
+  guint i, j;
+  FttVector g[FTT_DIMENSION];
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (u != NULL);
+
+  for (i = 0; i < FTT_DIMENSION; i++)
+    if (GFS_IS_MIXED (cell))
+      gfs_mixed_cell_gradient (cell, u[i], &g[i]);
+    else
+      for (j = 0; j < FTT_DIMENSION; j++)
+	(&g[i].x)[j] = gfs_center_gradient (cell, j, u[i]->i);			     
+
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    t[i][i] = (&g[i].x)[i];
+    for (j = i + 1; j < FTT_DIMENSION; j++)
+      t[i][j] = ((&g[j].x)[i] + (&g[i].x)[j])/2.;
+  }
+  for (i = 0; i < FTT_DIMENSION; i++)
+    for (j = 0; j < i; j++)
+      t[i][j] = t[j][i];
+}
+
+/**
+ * gfs_2nd_principal_invariant:
+ * @cell: a #FttCell.
+ * @u: the velocity.
+ *
+ * Returns: the second principal invariant of the shear strain rate
+ * tensor of @cell: sqrt(D:D).
+ */
+gdouble gfs_2nd_principal_invariant (FttCell * cell, GfsVariable ** u)
+{
+  gdouble t[FTT_DIMENSION][FTT_DIMENSION];
+  gdouble D = 0.;
+  guint i, j;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (u != NULL, 0.);
+
+  gfs_shear_strain_rate_tensor (cell, u, t);
+  for (i = 0; i < FTT_DIMENSION; i++)
+    for (j = 0; j < FTT_DIMENSION; j++)
+      D += t[i][j]*t[i][j];
+  return sqrt (D);
+}
+
+/**
+ * gfs_get_from_below_intensive:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable to "get from below".
+ *
+ * Sets the value of the "intensive" variable @v of @cell by taking
+ * the volume weighted average of the values of its children cells.
+ *
+ * This functions fails if @cell is a leaf of the cell tree.
+ */
+void gfs_get_from_below_intensive (FttCell * cell, const GfsVariable * v)
+{
+  gdouble val = 0., sa = 0.;
+  guint i;
+  FttCellChildren child;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (cell));
+  g_return_if_fail (v != NULL);
+
+  ftt_cell_children (cell, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      gdouble a = gfs_domain_cell_fraction (v->domain, child.c[i]);
+      val += GFS_VARIABLE (child.c[i], v->i)*a;
+      sa += a;
+    }
+  if (sa > 0.)
+    GFS_VARIABLE (cell, v->i) = val/sa;
+}
+
+/**
+ * gfs_cell_coarse_fine:
+ * @parent: a #FttCell.
+ * @v: a #GfsVariable.
+ *
+ * Initializes @v on the children of @parent using interpolation.
+ *
+ * First-order interpolation (straight injection) is used for boundary
+ * cells and second-order interpolation for the other cells.  
+ */
+void gfs_cell_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  guint n;
+
+  g_return_if_fail (parent != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (parent));
+  g_return_if_fail (v != NULL);
+
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++)
+    if (child.c[n])
+      GFS_VALUE (child.c[n], v) = GFS_VALUE (parent, v);
+
+  if (!GFS_CELL_IS_BOUNDARY (parent)) {
+    FttVector g;
+    FttComponent c;
+    
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&g.x)[c] = gfs_center_van_leer_gradient (parent, c, v->i);
+
+    if (v->domain->cell_metric) {
+      gdouble a[FTT_CELLS], sa = 0.;
+      for (n = 0; n < FTT_CELLS; n++) {
+	a[n] = (* v->domain->cell_metric) (v->domain, child.c[n]);
+	sa += a[n];
+      }
+      g_assert (sa > 0.);
+      sa *= 2.;
+#if FTT_2D
+      double gx1 = g.x*(a[0] + a[2])/sa, gx2 = - g.x*(a[1] + a[3])/sa;
+      double gy1 = g.y*(a[2] + a[3])/sa, gy2 = - g.y*(a[0] + a[1])/sa;
+      GFS_VALUE (child.c[0], v) += gx2 + gy1;
+      GFS_VALUE (child.c[1], v) += gx1 + gy1;
+      GFS_VALUE (child.c[2], v) += gx2 + gy2;
+      GFS_VALUE (child.c[3], v) += gx1 + gy2;
+#else /* 3D */
+      g_assert_not_implemented ();
+#endif /* 3D */
+    }
+    else
+      for (n = 0; n < FTT_CELLS; n++) 
+	if (child.c[n]) {
+	  FttVector p;
+	  
+	  ftt_cell_relative_pos (child.c[n], &p);
+	  for (c = 0; c < FTT_DIMENSION; c++)
+	    GFS_VALUE (child.c[n], v) += (&p.x)[c]*(&g.x)[c];
+	}
+  }
+}
+
+/**
+ * gfs_cell_cleanup:
+ * @cell: a #FttCell.
+ * @domain: a #GfsDomain.
+ *
+ * Frees the memory allocated for extra data associated with @cell.
+ *
+ * This function must be used as "cleanup function" when using
+ * ftt_cell_destroy().
+ */
+void gfs_cell_cleanup (FttCell * cell, GfsDomain * domain)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (domain != NULL);
+
+  if (cell->data) {
+    GSList * i = domain->variables;
+    while (i) {
+      GfsVariable * v = i->data;
+      if (v->cleanup)
+	(* v->cleanup) (cell, v);
+      i = i->next;
+    }
+    if (GFS_STATE (cell)->solid) {
+      g_free (GFS_STATE (cell)->solid);
+      GFS_STATE (cell)->solid = NULL;
+    }    
+  }
+  g_free (cell->data);
+  cell->data = NULL;
+}
+
+/**
+ * gfs_cell_reset:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable to reset.
+ *
+ * Sets the value of the variable @v of @cell to zero.
+ */
+void gfs_cell_reset (FttCell * cell, GfsVariable * v)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (v != NULL);
+
+  GFS_VARIABLE (cell, v->i) = 0.;
+}
+
+static void add_stats (const FttCell * cell, gpointer * data)
+{
+  GtsRange * s = data[0];
+  gdouble v = GFS_VARIABLE (cell, GFS_VARIABLE1 (data[1])->i);
+
+  if (v < G_MAXDOUBLE)
+    gts_range_add_value (s, v);
+}
+
+/**
+ * gfs_stats_variable:
+ * @root: the root #FttCell of the tree to obtain statistics from.
+ * @v: the variable to consider for statistics.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Traverses the cell tree defined by @root using ftt_cell_traverse()
+ * and gathers statistics about variable @v.
+ *
+ * Returns: a #GtsRange containing the statistics about @v.
+ */
+GtsRange gfs_stats_variable (FttCell * root,
+			     GfsVariable * v,
+			     FttTraverseFlags flags,
+			     gint max_depth)
+{
+  GtsRange s;
+  gpointer data[2];
+
+  g_return_val_if_fail (root != NULL, s);
+  g_return_val_if_fail (v != NULL, s);
+  
+  gts_range_init (&s);
+  data[0] = &s;
+  data[1] = v;
+  ftt_cell_traverse (root, FTT_PRE_ORDER, flags, max_depth, 
+		     (FttCellTraverseFunc) add_stats, data);
+  gts_range_update (&s);
+
+  return s;
+}
+
+static void add_norm (const FttCell * cell, gpointer * data)
+{
+  GfsNorm * n = data[0];
+  GfsVariable * v = data[1];
+
+  gfs_norm_add (n, GFS_VALUE (cell, v), gfs_cell_volume (cell, v->domain));
+}
+
+/**
+ * gfs_norm_variable:
+ * @root: the root #FttCell of the tree to obtain norm from.
+ * @v: the variable to consider for norm statistics.
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ *
+ * Traverses the cell tree defined by @root using ftt_cell_traverse()
+ * and gathers norm statistics about variable @v.
+ *
+ * Returns: a #GfsNorm containing the norm statistics about @v.
+ */
+GfsNorm gfs_norm_variable (FttCell * root,
+			   GfsVariable * v,
+			   FttTraverseFlags flags,
+			   gint max_depth)
+{
+  GfsNorm n;
+  gpointer data[2];
+
+  g_return_val_if_fail (root != NULL, n);
+  g_return_val_if_fail (v != NULL, n);
+  
+  gfs_norm_init (&n);
+  data[0] = &n;
+  data[1] = v;
+  ftt_cell_traverse (root, FTT_PRE_ORDER, flags, max_depth, 
+		     (FttCellTraverseFunc) add_norm, data);
+  gfs_norm_update (&n);
+
+  return n;
+}
+
+/**
+ * gfs_norm_init:
+ * @n: a #GfsNorm.
+ *
+ * Initializes a #GfsNorm.
+ */
+void gfs_norm_init (GfsNorm * n)
+{
+  g_return_if_fail (n != NULL);
+
+  n->bias = n->first = n->second = 0.;
+  n->infty = - G_MAXDOUBLE;
+  n->w = 0.;
+}
+
+/**
+ * gfs_norm_reset:
+ * @n: a #GfsNorm.
+ *
+ * Sets all the fields of @n to 0.
+ */
+void gfs_norm_reset (GfsNorm * n)
+{
+  g_return_if_fail (n != NULL);
+
+  n->bias = n->first = n->second = 0.;
+  n->infty = 0.;
+  n->w = 0.;
+}
+
+/**
+ * gfs_norm_add:
+ * @n: a #GfsNorm.
+ * @val: a value to add to @n.
+ * @weight: weight of @val.
+ *
+ * Adds @val to @n.
+ */
+void gfs_norm_add (GfsNorm * n, gdouble val, gdouble weight)
+{
+  g_return_if_fail (n != NULL);
+
+  if (val < G_MAXDOUBLE) {
+    n->bias += weight*val;
+    val = fabs (val);
+    if (weight != 0. && val > n->infty)
+      n->infty = val;
+    n->first += weight*val;
+    n->second += weight*val*val;
+    n->w += weight;
+  }
+}
+
+/**
+ * gfs_norm_update:
+ * @n: a #GfsNorm.
+ * 
+ * Updates the fields of @n.
+ */
+void gfs_norm_update (GfsNorm * n)
+{
+  g_return_if_fail (n != NULL);
+
+  if (n->w > 0.0) {
+    n->bias /= n->w;
+    n->first /= n->w;
+    n->second = sqrt (n->second/n->w);
+  }
+  else
+    n->infty = 0.0;
+}
+
+/**
+ * gfs_face_interpolated_value:
+ * @face: a #FttFace.
+ * @v: a #GfsVariable index.
+ *
+ * Computes the value of variable @v on the @face using second-order
+ * interpolation from the cell-centered values.
+ *
+ * Returns: the value of variable @v on the face.  
+ */
+gdouble gfs_face_interpolated_value (const FttCellFace * face,
+				     guint v)
+{
+  gdouble x1 = 1., v1;
+#if 1
+  g_return_val_if_fail (face != NULL, 0.);
+
+  if (face->neighbor) {
+    v1 = neighbor_value (face, v, &x1);
+    return ((x1 - 0.5)*GFS_VARIABLE (face->cell, v) + 0.5*v1)/x1;
+  }
+  else
+    return GFS_VARIABLE (face->cell, v);
+#else
+  gdouble v0;
+  FttCellFace f2;
+
+  g_return_val_if_fail (face != NULL, 0.);
+
+  v0 = GFS_VARIABLE (face->cell, v);
+  v1 = neighbor_value (face, v, &x1);
+  f2 = gfs_cell_face (face->cell, FTT_OPPOSITE_DIRECTION (face->d));
+  if (f2.neighbor) {
+    gdouble x2 = 1.;
+    gdouble v2 = neighbor_value (&f2, v, &x2);
+
+    return v0 + (x2*(v1 - v0)*(1. + 2.*x2) - x1*(v0 - v2)*(1. - 2.*x1))
+      /(4.*x1*x2*(x1 + x2));
+  }
+  else
+    return ((x1 - 0.5)*v0 + 0.5*v1)/x1;
+#endif
+}
+
+/**
+ * gfs_face_weighted_interpolated_value:
+ * @face: a #FttFace.
+ * @v: a #GfsVariable index.
+ *
+ * Computes the value of variable @v on the @face weighted by the
+ * value of the @v field of the face state vector using interpolation
+ * from the cell-centered values. The value returned is second order
+ * accurate in space and conservative, in the sense that values at a
+ * coarse/fine cell boundary are consistent.
+ *
+ * Returns: the weighted value of variable @v on the face.  
+ */
+gdouble gfs_face_weighted_interpolated_value (const FttCellFace * face,
+					      guint v)
+{
+  g_return_val_if_fail (face != NULL, 0.);
+
+  if (face->neighbor) {
+    if (FTT_CELL_IS_LEAF (face->neighbor)) {
+      gdouble w = GFS_STATE (face->cell)->f[face->d].v, x1 = 1., v1;
+      v1 = neighbor_value (face, v, &x1);
+      return w*((x1 - 0.5)*GFS_VARIABLE (face->cell, v) + 0.5*v1)/x1;
+    }
+    else {
+      /* neighbor is at a deeper level */
+      FttCellChildren children;
+      FttCellFace f;
+      gdouble val = 0.;
+      guint i, n;
+      
+      f.d = FTT_OPPOSITE_DIRECTION (face->d);
+      n = ftt_cell_children_direction (face->neighbor, f.d, &children);
+      f.neighbor = face->cell;
+      for (i = 0; i < n; i++)
+	if ((f.cell = children.c[i])) {
+	  gdouble w = GFS_STATE (f.cell)->f[f.d].v, x1 = 1., v1;
+	  v1 = neighbor_value (&f, v, &x1);
+	  val += w*v1;
+	}
+      return val/n;
+    }
+  }
+  else
+    return GFS_STATE (face->cell)->f[face->d].v*GFS_VARIABLE (face->cell, v);
+}
+
+/**
+ * gfs_normal_divergence:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable.
+ *
+ * Adds to variable @v of @cell the integral of the divergence
+ * of the (MAC) velocity field in this cell.  
+ */
+void gfs_normal_divergence (FttCell * cell,
+			    GfsVariable * v)
+{
+  FttCellFace face;
+  gdouble div = 0.;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (v != NULL);
+
+  face.cell = cell;
+  for (face.d = 0; face.d < FTT_NEIGHBORS; face.d++)
+    div += (FTT_FACE_DIRECT (&face) ? 1. : -1.)*
+      GFS_STATE (cell)->f[face.d].un*gfs_domain_face_fraction (v->domain, &face);
+  GFS_VALUE (cell, v) = div*ftt_cell_size (cell);
+}
+
+/**
+ * gfs_normal_divergence_2D:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable.
+ *
+ * Fills variable @v of @cell with the integral of the 2D
+ * divergence of the (MAC) velocity field in this cell.
+ */
+void gfs_normal_divergence_2D (FttCell * cell,
+			       GfsVariable * v)
+{
+  FttComponent c;
+  gdouble div = 0.;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (v != NULL);
+
+  if (GFS_IS_MIXED (cell)) {
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+    
+    for (c = 0; c < 2; c++) {
+      FttDirection d = 2*c;
+      
+      div += (solid->s[d]*GFS_STATE (cell)->f[d].un - 
+	      solid->s[d + 1]*GFS_STATE (cell)->f[d + 1].un);
+    }
+  }
+  else
+    for (c = 0; c < 2; c++) {
+      FttDirection d = 2*c;
+      
+      div += (GFS_STATE (cell)->f[d].un - 
+	      GFS_STATE (cell)->f[d + 1].un);
+    }
+  GFS_VARIABLE (cell, v->i) = div*ftt_cell_size (cell);
+}
+
+/**
+ * gfs_divergence:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * Returns: the divergence of the (centered) vector field @v in @cell.
+ */
+gdouble gfs_divergence (FttCell * cell,
+			GfsVariable ** v)
+{
+  FttComponent c;
+  gdouble div = 0.;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    div += gfs_center_gradient (cell, c, v[c]->i);
+  return div/ftt_cell_size (cell);
+}
+
+/**
+ * gfs_vorticity:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * Returns: the vorticity (norm of the vorticity vector in 3D) of the
+ * vector field @v in @cell.
+ */
+gdouble gfs_vorticity (FttCell * cell,
+		       GfsVariable ** v)
+{
+  gdouble size;
+#if (!FTT_2D)
+  FttVector vort;
+#endif /* FTT_3D */
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  size = ftt_cell_size (cell);
+#if FTT_2D
+  return (gfs_center_gradient (cell, FTT_X, v[1]->i) -
+	  gfs_center_gradient (cell, FTT_Y, v[0]->i))/size;
+#else  /* FTT_3D */
+  vort.x = (gfs_center_gradient (cell, FTT_Y, v[2]->i) -
+	    gfs_center_gradient (cell, FTT_Z, v[1]->i))/size;
+  vort.y = (gfs_center_gradient (cell, FTT_Z, v[0]->i) -
+	    gfs_center_gradient (cell, FTT_X, v[2]->i))/size;
+  vort.z = (gfs_center_gradient (cell, FTT_X, v[1]->i) -
+	    gfs_center_gradient (cell, FTT_Y, v[0]->i))/size;
+  return sqrt (vort.x*vort.x + vort.y*vort.y + vort.z*vort.z);
+#endif /* FTT_3D */
+}
+
+/**
+ * gfs_vector_norm2:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * Returns: the squared norm of the vector field @v in @cell.
+ */
+gdouble gfs_vector_norm2 (FttCell * cell,
+			  GfsVariable ** v)
+{
+  FttComponent c;
+  gdouble n = 0.;
+  
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    n += GFS_VARIABLE (cell, v[c]->i)*GFS_VARIABLE (cell, v[c]->i);
+  return n;
+}
+
+/**
+ * gfs_vector_norm:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * Returns: the norm of the vector field @v in @cell.
+ */
+gdouble gfs_vector_norm (FttCell * cell,
+			 GfsVariable ** v)
+{
+  return sqrt (gfs_vector_norm2 (cell, v));
+}
+
+/**
+ * gfs_vector_lambda2:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * Returns: The value of the lambda2 eigenvalue used by Jeong and
+ * Hussain as vortex criterion (JFM 285, 69-94, 1995), normalized by
+ * the square of the size of the cell.
+ */
+gdouble gfs_vector_lambda2 (FttCell * cell,
+			    GfsVariable ** v)
+{
+  gdouble J[FTT_DIMENSION][FTT_DIMENSION];
+  gdouble S2O2[FTT_DIMENSION][FTT_DIMENSION];
+  gdouble lambda[FTT_DIMENSION], ev[FTT_DIMENSION][FTT_DIMENSION];
+  guint i, j, k;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  for (i = 0; i < FTT_DIMENSION; i++)
+    for (j = 0; j < FTT_DIMENSION; j++)
+      J[i][j] = gfs_center_gradient (cell, j, v[i]->i);
+  for (i = 0; i < FTT_DIMENSION; i++)
+    for (j = 0; j < FTT_DIMENSION; j++) {
+      S2O2[i][j] = 0.;
+      for (k = 0; k < FTT_DIMENSION; k++)
+	S2O2[i][j] += J[i][k]*J[k][j] + J[k][i]*J[j][k];
+    }
+  gfs_eigenvalues (S2O2, lambda, ev);
+  return lambda[1]/2.;
+}
+
+/**
+ * gfs_pressure_force:
+ * @cell: a #FttCell.
+ * @p: a #GfsVariable.
+ * @f: a #FttVector.
+ *
+ * Fills @f with the pressure @p component of the force exerted by the
+ * fluid on the fraction of embedded boundary contained in @cell.
+ */
+void gfs_pressure_force (FttCell * cell,
+			 GfsVariable * p,
+			 FttVector * f)
+{
+  GfsSolidVector * s;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (f != NULL);
+
+  if ((s = GFS_STATE (cell)->solid)) {
+    gdouble size = ftt_cell_size (cell);
+    gdouble pv = gfs_cell_dirichlet_value (cell, p, -1)*size;
+    FttComponent c;
+
+#if (!FTT_2D)
+    pv *= size;
+#endif /* 3D */
+
+    gfs_solid_normal (cell, f);
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&f->x)[c] *= pv;
+  }
+  else
+    f->x = f->y = f->z = 0.;
+}
+
+static void cell_traverse_mixed (FttCell * cell,
+				 FttTraverseType order,
+				 FttTraverseFlags flags,
+				 FttCellTraverseFunc func,
+				 gpointer data)
+{
+  if (!GFS_IS_MIXED (cell))
+    return;
+  if (order == FTT_PRE_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, data);
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    struct _FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_mixed (c, order, flags, func, data);
+    }
+  }
+  if (order == FTT_POST_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, data);
+}
+
+/**
+ * gfs_cell_traverse_mixed:
+ * @root: the root #FttCell of the tree to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * 
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each mixed cell.
+ */
+void gfs_cell_traverse_mixed (FttCell * root,
+			      FttTraverseType order,
+			      FttTraverseFlags flags,
+			      FttCellTraverseFunc func,
+			      gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (func != NULL);
+
+  cell_traverse_mixed (root, order, flags, func, data);
+}
+
+#if FTT_2D
+static FttDirection corner[4][FTT_DIMENSION] = {
+  { FTT_LEFT,  FTT_BOTTOM },
+  { FTT_RIGHT, FTT_BOTTOM },
+  { FTT_RIGHT, FTT_TOP },
+  { FTT_LEFT,  FTT_TOP }
+};
+#else  /* 3D */
+static FttDirection corner[8][FTT_DIMENSION] = {
+  { FTT_LEFT,  FTT_BOTTOM, FTT_FRONT },
+  { FTT_RIGHT, FTT_BOTTOM, FTT_FRONT },
+  { FTT_RIGHT, FTT_TOP,    FTT_FRONT },
+  { FTT_LEFT,  FTT_TOP,    FTT_FRONT },
+  { FTT_LEFT,  FTT_BOTTOM, FTT_BACK },
+  { FTT_RIGHT, FTT_BOTTOM, FTT_BACK },
+  { FTT_RIGHT, FTT_TOP,    FTT_BACK },
+  { FTT_LEFT,  FTT_TOP,    FTT_BACK }
+};
+#endif /* 3D */
+
+/**
+ * gfs_interpolate:
+ * @cell: a #FttCell containing location @p.
+ * @p: the location at which to interpolate.
+ * @v: a #GfsVariable.
+ *
+ * Interpolates the @v variable of @cell, at location @p. Linear
+ * interpolation is used and the boundaries of the domain are treated
+ * as planes of symmetry for all variables.
+ *
+ * Returns: the interpolated value of variable @v at location @p.
+ */
+gdouble gfs_interpolate (FttCell * cell,
+			 FttVector p,
+			 GfsVariable * v)
+{
+  FttVector o;
+  gdouble size;
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  ftt_cell_pos (cell, &o);
+  size = ftt_cell_size (cell)/2.;
+  p.x = (p.x - o.x)/size;
+  p.y = (p.y - o.y)/size;
+#if FTT_2D
+  {
+    gdouble f[4], a, b, c, d;
+
+    for (i = 0; i < 4; i++)
+      f[i] = gfs_cell_corner_value (cell, corner[i], v, -1);
+
+    a = f[1] + f[2] - f[0] - f[3];
+    b = f[2] + f[3] - f[0] - f[1];
+    c = f[0] - f[1] + f[2] - f[3];
+    d = f[0] + f[1] + f[2] + f[3];
+
+    return (a*p.x + b*p.y + c*p.x*p.y + d)/4.;
+  }
+#else  /* 3D */
+  {
+    gdouble f[8], c[8];
+    
+    p.z = (p.z - o.z)/size;
+    for (i = 0; i < 8; i++)
+      f[i] = gfs_cell_corner_value (cell, corner[i], v, -1);
+
+    c[0] = - f[0] + f[1] + f[2] - f[3] - f[4] + f[5] + f[6] - f[7];
+    c[1] = - f[0] - f[1] + f[2] + f[3] - f[4] - f[5] + f[6] + f[7];
+    c[2] =   f[0] + f[1] + f[2] + f[3] - f[4] - f[5] - f[6] - f[7];
+    c[3] =   f[0] - f[1] + f[2] - f[3] + f[4] - f[5] + f[6] - f[7];
+    c[4] = - f[0] + f[1] + f[2] - f[3] + f[4] - f[5] - f[6] + f[7];
+    c[5] = - f[0] - f[1] + f[2] + f[3] + f[4] + f[5] - f[6] - f[7];
+    c[6] =   f[0] - f[1] + f[2] - f[3] - f[4] + f[5] - f[6] + f[7];
+    c[7] =   f[0] + f[1] + f[2] + f[3] + f[4] + f[5] + f[6] + f[7];
+
+    return (c[0]*p.x + c[1]*p.y + c[2]*p.z + 
+	    c[3]*p.x*p.y + c[4]*p.x*p.z + c[5]*p.y*p.z + 
+	    c[6]*p.x*p.y*p.z + 
+	    c[7])/8.;
+  }
+#endif /* 3D */
+}
+
+/**
+ * gfs_interpolate_stencil:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable.
+ *
+ * Sets to 1. the @v variable of all the cells which would be used by
+ * a call to gfs_interpolate().
+ */
+void gfs_interpolate_stencil (FttCell * cell,
+			      GfsVariable * v)
+{
+  guint i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (v != NULL);
+
+  for (i = 0; i < (FTT_DIMENSION == 2 ? 4 : 8); i++) {
+    GfsInterpolator inter;
+    guint j;
+
+    gfs_cell_corner_interpolator (cell, corner[i], -1, TRUE, &inter);
+    for (j = 0; j < inter.n; j++)
+      GFS_VARIABLE (inter.c[j], v->i) = 1.;
+  }
+}
+
+/**
+ * gfs_center_curvature:
+ * @cell: a #FttCell.
+ * @c: a component.
+ * @v: a #GfsVariable index.
+ *
+ * The curvature is normalized by the square of the size of the cell.
+ *
+ * Returns: the value of the @c component of the curvature of variable @v
+ * at the center of the cell.  
+ */
+gdouble gfs_center_curvature (FttCell * cell,
+			      FttComponent c,
+			      guint v)
+{
+  FttCellFace f;
+  GfsGradient g = { 0., 0. };
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (c < FTT_DIMENSION, 0.);
+
+  if (GFS_IS_MIXED (cell))
+    return 0.;
+
+  f.cell = cell;
+  for (f.d = 2*c; f.d <= 2*c + 1; f.d++)
+    if ((f.neighbor = ftt_cell_neighbor (cell, f.d))) {
+      GfsGradient e;
+
+      gfs_face_gradient (&f, &e, v, -1);
+      g.a += e.a;
+      g.b += e.b;
+    }
+
+  return g.b - g.a*GFS_VARIABLE (cell, v);
+}
+
+/**
+ * gfs_streamline_curvature:
+ * @cell: a #FttCell.
+ * @v: the components of the vector.
+ *
+ * The curvature is normalized by the size of the cell.
+ *
+ * Returns: the value of the curvature of the streamline defined by @v passing
+ * through the center of the cell.
+ */
+gdouble gfs_streamline_curvature (FttCell * cell,
+				  GfsVariable ** v)
+{
+  gdouble u2;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  u2 = gfs_vector_norm2 (cell, v);
+
+  if (u2 == 0.)
+    return 0.;
+  else {
+    FttComponent i;
+    gdouble ugu = 0.;
+
+    for (i = 0; i < FTT_DIMENSION; i++) {
+      FttComponent j;
+      gdouble ugui = 0.;
+
+      for (j = 0; j < FTT_DIMENSION; j++)
+	ugui += GFS_VARIABLE (cell, v[j]->i)*gfs_center_gradient (cell, j, v[i]->i);
+      ugu += ugui*ugui;
+    }
+    return sqrt (ugu)/u2;
+  }
+}
+
+static FttCell * cell_corner_neighbor (FttCell * cell,
+				       FttDirection * d,
+				       gint max_level,
+				       gboolean * t_junction)
+{
+  FttCell * neighbor = ftt_cell_neighbor (cell, d[0]);
+  if (!neighbor)
+    return NULL;
+  else {
+    guint level = ftt_cell_level (cell);
+    if (ftt_cell_level (neighbor) < level) {
+      /* neighbor is at a shallower level */
+      if (ftt_cell_child_corner (ftt_cell_parent (cell), d) != cell)
+	*t_junction = TRUE;
+      return neighbor;
+    }
+    else {
+      if (level == max_level || FTT_CELL_IS_LEAF (neighbor))
+	/* neighbor is at the same level */
+	return neighbor;
+      else {
+	/* neighbor is at a deeper level */
+	FttCell * n;
+	guint i;
+	FttDirection d1[FTT_DIMENSION];
+	d1[0] = FTT_OPPOSITE_DIRECTION (d[0]);
+	for (i = 1; i < FTT_DIMENSION; i++)
+	  d1[i] = d[i];
+	n = ftt_cell_child_corner (neighbor, d1);
+	return n ? n : neighbor;
+      }
+    }
+  }
+}
+
+static void interpolator_merge (GfsInterpolator * a, GfsInterpolator * b)
+{
+  guint i;
+  for (i = 0; i < b->n; i++) {
+    FttCell * c = b->c[i];
+    guint j;
+
+    for (j = 0; j < a->n && c != a->c[j]; j++)
+      ;
+    if (j < a->n)
+      a->w[j] += b->w[i];
+    else {
+#if FTT_2D
+      g_assert (j < 7);
+#else
+      g_assert (j < 29);
+#endif
+      a->c[j] = c;
+      a->w[j] = b->w[i];
+      a->n++;
+    }
+  }
+}
+
+static void interpolator_scale (GfsInterpolator * a, gdouble b)
+{
+  guint i;
+  for (i = 0; i < a->n; i++)
+    a->w[i] *= b;
+}
+
+static void t_junction_interpolator (FttCell * cell,
+				     FttDirection * d,
+				     FttCell * n,
+				     gint max_level,
+				     gboolean centered,
+				     GfsInterpolator * inter)
+{
+  FttDirection d1[FTT_DIMENSION];
+  GfsInterpolator a;
+
+  d1[0] = FTT_OPPOSITE_DIRECTION (d[0]);
+#if FTT_2D
+  d1[1] = d[1];
+  gfs_cell_corner_interpolator (n, d1, max_level, centered, inter);
+  d1[1] = FTT_OPPOSITE_DIRECTION (d[1]);
+  gfs_cell_corner_interpolator (n, d1, max_level, centered, &a);
+  interpolator_merge (inter, &a);
+  interpolator_scale (inter, 0.5);
+#else /* 3D */
+  d1[1] = d[1]; d1[2] = d[2];
+  gfs_cell_corner_interpolator (n, d1, max_level, centered, inter);
+  if (ftt_cell_neighbor_is_brother (cell, d[1])) {
+    d1[1] = FTT_OPPOSITE_DIRECTION (d[1]);
+    gfs_cell_corner_interpolator (n, d1, max_level, centered, &a);
+    interpolator_merge (inter, &a);
+    if (ftt_cell_neighbor_is_brother (cell, d[2])) {
+      d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+      gfs_cell_corner_interpolator (n, d1, max_level, centered, &a);
+      interpolator_merge (inter, &a);
+      d1[1] = d[1];
+      gfs_cell_corner_interpolator (n, d1, max_level, centered, &a);
+      interpolator_merge (inter, &a);
+      interpolator_scale (inter, 0.25);
+    }
+    else
+      interpolator_scale (inter, 0.5);
+  }
+  else {
+    d1[2] = FTT_OPPOSITE_DIRECTION (d[2]);
+    gfs_cell_corner_interpolator (n, d1, max_level, centered, &a);
+    interpolator_merge (inter, &a);
+    interpolator_scale (inter, 0.5);
+  }
+#endif /* 3D */
+}
+
+static gboolean do_path (FttCell * cell, gint i,
+			 FttCell * n[N_CELLS],
+			 FttDirection * d,
+			 gint max_level,
+			 gboolean centered,
+			 GfsInterpolator * inter)
+{
+  /* paths from each cell to neighbors. Cell indices are as in
+     doc/figures/indices.fig
+     first index: cell index
+     second index: path index
+     third index: < FTT_DIMENSION: directions.
+                  = FTT_DIMENSION: neighboring cell index */
+  static gint path[N_CELLS][FTT_DIMENSION][FTT_DIMENSION + 1] = {
+#if FTT_2D
+    {{1,2,1},   {2,1,2}},
+    {{2,-1,3},  {-1,2,0}},
+    {{1,-2,3},  {-2,1,0}},
+    {{-1,-2,2}, {-2,-1,1}}
+#else /* 3D */
+    {{1,2,3,1},    {2,1,3,2},    {3,1,2,4}},
+    {{2,3,-1,3},   {3,2,-1,5},   {-1,2,3,0}},
+    {{1,-2,3,3},   {3,-2,1,6},   {-2,3,1,0}},
+    {{3,-1,-2,7},  {-2,-1,3,1},  {-1,-2,3,2}},
+    {{2,1,-3,6},   {1,2,-3,5},   {-3,1,2,0}},
+    {{2,-1,-3,7},  {-1,2,-3,4},  {-3,2,-1,1}},
+    {{1,-2,-3,7},  {-2,1,-3,4},  {-3,1,-2,2}},
+    {{-1,-2,-3,6}, {-2,-1,-3,5}, {-3,-1,-2,3}}
+#endif /* 3D */
+  };
+  guint j;
+
+  for (j = 0; j < FTT_DIMENSION; j++) {
+    guint k = path[i][j][FTT_DIMENSION];
+
+    if (n[k] == NULL) {
+      gboolean t_junction = FALSE;
+      FttDirection d1[FTT_DIMENSION];
+      guint l;
+
+      for (l = 0; l < FTT_DIMENSION; l++)
+	d1[l] = path[i][j][l] < 0 ? FTT_OPPOSITE_DIRECTION (d[- path[i][j][l] - 1]) : 
+	  d[path[i][j][l] - 1];
+      n[k] = cell_corner_neighbor (cell, d1, max_level, &t_junction);
+      if (t_junction) {
+	t_junction_interpolator (cell, d1, n[k], max_level, centered, inter);
+	return TRUE;
+      }
+      if (n[k]) {
+	t_junction = do_path (n[k], k, n, d, max_level, centered, inter);
+	if (t_junction)
+	  return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+static gdouble distance (FttVector * c, FttCell * cell, gboolean centered)
+{
+  if (centered || !GFS_IS_MIXED (cell))
+    return ftt_cell_size (cell)*
+#if FTT_2D
+      0.707106781185
+#else  /* 3D */
+      0.866025403785
+#endif /* 3D */
+      ;
+  else {
+    FttVector cm;
+    gfs_cell_cm (cell, &cm);
+    return sqrt ((cm.x - c->x)*(cm.x - c->x) + (cm.y - c->y)*(cm.y - c->y)
+#if (!FTT_2D)
+      + (cm.z - c->z)*(cm.z - c->z)
+#endif /* 3D */
+		 );
+  }
+}
+
+/**
+ * gfs_cell_corner_interpolator:
+ * @cell: a #FttCell.
+ * @d: a set of perpendicular directions.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ * @centered: %TRUE if the interpolator is cell-centered.
+ * @inter: a #GfsInterpolator.
+ *
+ * Fills @inter with the interpolator for the corner of @cell defined by @d.
+ */
+void gfs_cell_corner_interpolator (FttCell * cell,
+				   FttDirection d[FTT_DIMENSION],
+				   gint max_level,
+				   gboolean centered,
+				   GfsInterpolator * inter)
+{
+  FttCell * n[N_CELLS];
+  guint i;
+  gboolean t_junction;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (inter != NULL);
+
+  while (!FTT_CELL_IS_LEAF (cell) && 
+	 ftt_cell_level (cell) != max_level &&
+	 (n[0] = ftt_cell_child_corner (cell, d)))
+    cell = n[0];
+  n[0] = cell;
+  for (i = 1; i < N_CELLS; i++)
+    n[i] = NULL;
+  t_junction = do_path (cell, 0, n, d, max_level, centered, inter);
+  if (t_junction)
+    return;
+
+  {
+    FttVector c;
+    gdouble w = 0.;
+
+    inter->n = 0;
+    ftt_corner_pos (cell, d, &c);
+    for (i = 0; i < N_CELLS; i++)
+      if (n[i]) {
+	gdouble a;
+	a = 1./(distance (&c, n[i], centered) + 1e-12);
+	inter->c[inter->n] = n[i];
+	inter->w[inter->n++] = a;
+	w += a;
+      }
+    g_assert (w > 0.);
+    interpolator_scale (inter, 1./w);
+  }
+}
+
+/**
+ * gfs_cell_corner_value:
+ * @cell: a #FttCell.
+ * @d: a set of perpendicular directions.
+ * @v: a #GfsVariable.
+ * @max_level: the maximum cell level to consider (-1 means no restriction).
+ *
+ * Returns: the value of variable @v interpolated at the corner of
+ * @cell defined by @d.
+ */
+gdouble gfs_cell_corner_value (FttCell * cell,
+			       FttDirection d[FTT_DIMENSION],
+			       GfsVariable * v,
+			       gint max_level)
+{
+  GfsInterpolator inter;
+  gdouble val = 0.;
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (v != NULL, 0.);
+
+  gfs_cell_corner_interpolator (cell, d, max_level, v->centered, &inter);
+  for (i = 0; i < inter.n; i++)
+    val += inter.w[i]*GFS_VARIABLE (inter.c[i], v->i);
+  return val;
+}
diff --git a/src/fluid.h b/src/fluid.h
new file mode 100644
index 0000000..019e7d0
--- /dev/null
+++ b/src/fluid.h
@@ -0,0 +1,261 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __FLUID_H__
+#define __FLUID_H__
+
+#include <gts.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "ftt.h"
+
+typedef struct _GfsVariable               GfsVariable;
+typedef struct _GfsDerivedVariable        GfsDerivedVariable;
+typedef struct _GfsDomain                 GfsDomain;
+
+typedef struct _GfsStateVector     GfsStateVector;
+typedef struct _GfsSolidVector     GfsSolidVector;
+typedef struct _GfsFaceStateVector GfsFaceStateVector;
+
+struct _GfsFaceStateVector {
+  gdouble un;
+  gdouble v;
+};
+
+struct _GfsStateVector {
+  /* temporary face variables */
+  GfsFaceStateVector f[FTT_NEIGHBORS];
+
+  /* solid boundaries */
+  GfsSolidVector * solid;
+
+  gdouble place_holder;
+};
+
+struct _GfsSolidVector {
+  gdouble s[FTT_NEIGHBORS];
+  gdouble a, v, fv;
+  FttCell * merged;
+  FttVector cm, ca;
+};
+
+typedef enum {
+  GFS_FLAG_USED =              1 <<  FTT_FLAG_USER,
+  GFS_FLAG_BOUNDARY          = 1 << (FTT_FLAG_USER + 1),
+  GFS_FLAG_DIRICHLET         = 1 << (FTT_FLAG_USER + 2),
+  GFS_FLAG_GRADIENT_BOUNDARY = 1 << (FTT_FLAG_USER + 3),
+  GFS_FLAG_PERMANENT         = 1 << (FTT_FLAG_USER + 4),
+  GFS_FLAG_THIN              = 1 << (FTT_FLAG_USER + 5),
+  GFS_FLAG_USER =                    FTT_FLAG_USER + 6 /* user flags start here */
+} GfsFlags;
+
+#define GFS_STATE(cell)               ((GfsStateVector *) (cell)->data)
+#define GFS_VARIABLE(cell, index)     ((&GFS_STATE (cell)->place_holder)[index])
+
+#define GFS_FACE_NORMAL_VELOCITY(fa)\
+  (GFS_STATE ((fa)->cell)->f[(fa)->d].un)
+#define GFS_FACE_NORMAL_VELOCITY_LEFT(fa)\
+  (GFS_STATE ((fa)->cell)->f[(fa)->d].un)
+#define GFS_FACE_NORMAL_VELOCITY_RIGHT(fa)\
+  (GFS_STATE ((fa)->neighbor)->f[FTT_OPPOSITE_DIRECTION ((fa)->d)].un)
+
+#define GFS_FACE_FRACTION(fa) (GFS_IS_MIXED ((fa)->cell) ?\
+                               GFS_STATE ((fa)->cell)->solid->s[(fa)->d] : 1.)
+#define GFS_FACE_FRACTION_LEFT(fa) GFS_FACE_FRACTION(fa)
+#define GFS_FACE_FRACTION_RIGHT(fa) (GFS_IS_MIXED ((fa)->neighbor) ?\
+                 GFS_STATE ((fa)->neighbor)->solid->s[FTT_OPPOSITE_DIRECTION ((fa)->d)] : 1.)
+
+#define GFS_IS_FLUID(cell)      ((cell) != NULL &&\
+                                 GFS_STATE (cell)->solid == NULL)
+#define GFS_IS_MIXED(cell)      ((cell) != NULL &&\
+                                 GFS_STATE (cell)->solid != NULL)
+#define GFS_CELL_IS_BOUNDARY(cell) (((cell)->flags & GFS_FLAG_BOUNDARY) != 0)
+#define GFS_CELL_IS_PERMANENT(cell) (((cell)->flags & GFS_FLAG_PERMANENT) != 0)
+#define GFS_CELL_IS_GRADIENT_BOUNDARY(cell) (((cell)->flags & GFS_FLAG_GRADIENT_BOUNDARY) != 0)
+
+FttCellFace           gfs_cell_face                 (FttCell * cell,
+						     FttDirection d);
+void                  gfs_cell_cleanup              (FttCell * cell,
+						     GfsDomain * domain);
+void                  gfs_cell_reset                (FttCell * cell, 
+						     GfsVariable * v);
+void                  gfs_get_from_below_intensive  (FttCell * cell, 
+						     const GfsVariable * v);
+void                  gfs_cell_coarse_fine          (FttCell * cell,
+						     GfsVariable * v);
+gdouble               gfs_face_interpolated_value   (const FttCellFace * face,
+						     guint v);
+gdouble               gfs_face_weighted_interpolated_value (const FttCellFace * face,
+							    guint v);
+typedef gdouble    (* GfsCenterGradient)            (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+gdouble               gfs_center_gradient           (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+void                  gfs_center_gradient_stencil   (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+gdouble               gfs_center_van_leer_gradient  (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+gdouble               gfs_center_minmod_gradient    (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+gdouble               gfs_center_regular_gradient   (FttCell * cell,
+						     FttComponent c,
+						     GfsVariable * v);
+gdouble               gfs_center_regular_2nd_derivative (FttCell * cell, 
+							 FttComponent c, 
+							 GfsVariable * v);
+
+typedef struct _GfsGradient GfsGradient;
+
+struct _GfsGradient {
+  gdouble a, b;
+};
+
+void                  gfs_face_gradient              (const FttCellFace * face,
+						      GfsGradient * g,
+						      guint v,
+						      gint max_level);
+void                  gfs_face_weighted_gradient     (const FttCellFace * face,
+						      GfsGradient * g,
+						      guint v,
+						      gint max_level);
+void                  gfs_face_weighted_gradient_2D  (const FttCellFace * face,
+						      GfsGradient * g,
+						      guint v,
+						      gint max_level);
+void                  gfs_face_gradient_flux         (const FttCellFace * face,
+						      GfsGradient * g,
+						      guint v,
+						      gint max_level);
+void                  gfs_cell_dirichlet_gradient    (FttCell * cell,
+						      guint v,
+						      gint max_level,
+						      gdouble v0,
+						      FttVector * grad);
+void                  gfs_mixed_cell_gradient        (FttCell * cell,
+						      GfsVariable * v,
+						      FttVector * g);
+gdouble               gfs_cell_dirichlet_gradient_flux (FttCell * cell,
+							guint v,
+							gint max_level,
+							gdouble v0);
+gdouble               gfs_cell_dirichlet_value         (FttCell * cell,
+							GfsVariable * v,
+							gint max_level);
+gdouble               gfs_mixed_cell_interpolate       (FttCell * cell,
+							FttVector p,
+							GfsVariable * v);
+
+void                  gfs_normal_divergence          (FttCell * cell,
+						      GfsVariable * v);
+void                  gfs_normal_divergence_2D       (FttCell * cell,
+						      GfsVariable * v);
+gdouble               gfs_divergence                 (FttCell * cell,
+						      GfsVariable ** v);
+gdouble               gfs_vorticity                  (FttCell * cell,
+						      GfsVariable ** v);
+gdouble               gfs_vector_norm                (FttCell * cell,
+						      GfsVariable ** v);
+gdouble               gfs_vector_norm2               (FttCell * cell,
+						      GfsVariable ** v);
+gdouble               gfs_vector_lambda2             (FttCell * cell,
+						      GfsVariable ** v);
+void                  gfs_pressure_force             (FttCell * cell,
+						      GfsVariable * p,
+						      FttVector * f);
+GtsRange              gfs_stats_variable             (FttCell * root, 
+						      GfsVariable * v, 
+						      FttTraverseFlags flags,
+						      gint max_depth);
+
+typedef struct _GfsNorm GfsNorm;
+
+struct _GfsNorm {
+  gdouble bias, first, second, infty, w;
+};
+
+void                  gfs_norm_init                 (GfsNorm * n);
+void                  gfs_norm_reset                (GfsNorm * n);
+void                  gfs_norm_add                  (GfsNorm * n, 
+						     gdouble val,
+						     gdouble weight);
+void                  gfs_norm_update               (GfsNorm * n);
+
+GfsNorm               gfs_norm_variable             (FttCell * root, 
+						     GfsVariable * v, 
+						     FttTraverseFlags flags,
+						     gint max_depth);
+  
+void                  gfs_cell_traverse_mixed       (FttCell * root,
+						     FttTraverseType order,
+						     FttTraverseFlags flags,
+						     FttCellTraverseFunc func,
+						     gpointer data);
+gdouble               gfs_interpolate               (FttCell * cell,
+						     FttVector p,
+						     GfsVariable * v);
+void                  gfs_interpolate_stencil       (FttCell * cell,
+						     GfsVariable * v);
+void                  ftt_cell_refine_corners       (FttCell * cell,
+						     FttCellInitFunc init,
+						     gpointer data);
+gdouble               gfs_center_curvature          (FttCell * cell,
+						     FttComponent c,
+						     guint v);
+gdouble               gfs_streamline_curvature      (FttCell * cell,
+						     GfsVariable ** v);
+void                  gfs_shear_strain_rate_tensor  (FttCell * cell, 
+						     GfsVariable ** u,
+						     gdouble t[FTT_DIMENSION][FTT_DIMENSION]);
+gdouble               gfs_2nd_principal_invariant   (FttCell * cell, 
+						     GfsVariable ** u);
+
+typedef struct {
+#if FTT_2D
+  FttCell * c[7];
+  gdouble w[7];
+#else  /* 3D */
+  FttCell * c[29];
+  gdouble w[29];
+#endif /* 3D */
+  guint n;  
+} GfsInterpolator;
+
+void                  gfs_cell_corner_interpolator  (FttCell * cell,
+						     FttDirection d[FTT_DIMENSION],
+						     gint max_level,
+						     gboolean centered,
+						     GfsInterpolator * inter);
+gdouble               gfs_cell_corner_value         (FttCell * cell,
+						     FttDirection * d,
+						     GfsVariable * v,
+						     gint max_level);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __FLUID_H__ */
diff --git a/src/ftt.c b/src/ftt.c
new file mode 100644
index 0000000..0429cbd
--- /dev/null
+++ b/src/ftt.c
@@ -0,0 +1,2445 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "ftt.h"
+
+#define  FTT_CELL_IS_DESTROYED(c) (((c)->flags & FTT_FLAG_DESTROYED) != 0)
+
+gchar * ftt_direction_name[FTT_NEIGHBORS] = {
+  "right", "left", "top", "bottom"
+#if (!FTT_2D)
+  , "front", "back"
+#endif /* FTT_3D || FTT_2D3 */
+};
+
+gint ftt_opposite_direction[FTT_NEIGHBORS] =
+#if      FTT_2D
+  {1, 0, 3, 2};
+#else  /* FTT_3D || FTT_2D3 */
+  {1, 0, 3, 2, 5, 4};
+#endif /* FTT_3D || FTT_2D3 */
+
+typedef struct _FttOct      FttOct;
+typedef struct _FttRootCell FttRootCell;
+
+static void oct_new (FttCell * parent,
+		     gboolean check_neighbors,
+		     FttCellInitFunc init,
+		     gpointer data)
+{
+  FttOct * oct;
+  guint n;
+
+  g_assert (parent != NULL);
+  g_assert (parent->children == NULL);
+
+  oct = g_malloc0 (sizeof (FttOct));
+  oct->level = ftt_cell_level (parent);
+  oct->parent = parent;
+#ifdef FTT_2D3
+  oct->dz = ftt_cell_dz (parent);
+#endif
+  ftt_cell_pos (parent, &(oct->pos));
+  ftt_cell_neighbors (parent, &(oct->neighbors));
+
+  for (n = 0; n < FTT_CELLS; n++) {
+    oct->cell[n].parent = oct;
+    oct->cell[n].flags = n;
+  }
+
+  if (check_neighbors)
+    for (n = 0; n < FTT_NEIGHBORS; n++) {
+      FttCell * neighbor = oct->neighbors.c[n];
+      
+      if (neighbor && ftt_cell_level (neighbor) < oct->level) {
+	oct_new (neighbor, check_neighbors, init, data);
+	oct->neighbors.c[n] = ftt_cell_neighbor (parent, n);
+      }
+    }
+
+  g_assert (parent->children == NULL);
+  parent->children = oct;
+
+  if (init)
+    (* init) (parent, data);
+}
+
+/**
+ * ftt_cell_new:
+ * @init: a #FttCellInitFunc or %NULL.
+ * @data: user data to pass to @init.
+ *
+ * Returns: a new root #FttCell, initialized by calling @init (if not %NULL).
+ */
+FttCell * ftt_cell_new (FttCellInitFunc init,
+			gpointer data)
+{
+  FttCell * cell;
+
+  cell = g_malloc0 (sizeof (FttRootCell));
+#ifdef FTT_2D3
+  FTT_ROOT_CELL (cell)->dz = 1.;
+#endif
+  if (init)
+    (* init) (cell, data);
+
+  return cell;
+}
+
+/**
+ * ftt_cell_check:
+ * @cell: a #FttCell.
+ *
+ * Returns: %TRUE if cell is consistent, %FALSE otherwise.
+ */
+gboolean ftt_cell_check (const FttCell * cell)
+{
+  FttCellNeighbors neighbor;
+  guint i, level;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+
+  ftt_cell_neighbors (cell, &neighbor);
+  level = ftt_cell_level (cell);
+  for (i = 0; i < FTT_NEIGHBORS; i++)
+    if (neighbor.c[i] && 
+	!FTT_CELL_IS_LEAF (neighbor.c[i]) &&
+	ftt_cell_level (neighbor.c[i]) == level &&
+	neighbor.c[i]->children->neighbors.c[FTT_OPPOSITE_DIRECTION (i)] != cell) {
+      g_warning ("ftt_cell_check (%p): neighbor %d = %p: %d/%d",
+		 cell, 
+		 i,		 
+	  neighbor.c[i]->children->neighbors.c[FTT_OPPOSITE_DIRECTION (i)],
+		 ftt_cell_level (neighbor.c[i]),
+		 ftt_cell_level (neighbor.c[i]->children->neighbors.c[FTT_OPPOSITE_DIRECTION (i)]));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * ftt_cell_refine_single:
+ * @cell: a #FttCell.
+ * @init: a #FttCellInitFunc or %NULL.
+ * @init_data: user data to pass to @init.
+ *
+ * Refines @cell and eventually its neighbors to ensure that the
+ * neighborhood properties are preserved. The new refined cells
+ * created are initialized using @init (if not %NULL).  
+ */
+void ftt_cell_refine_single (FttCell * cell,
+			     FttCellInitFunc init,
+			     gpointer init_data)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (FTT_CELL_IS_LEAF (cell));
+
+  oct_new (cell, TRUE, init, init_data);
+}
+
+/**
+ * ftt_cell_refine:
+ * @root: a #FttCell.
+ * @refine: a #FttCellRefineFunc.
+ * @refine_data: user data to pass to @refine.
+ * @init: a #FttCellInitFunc or %NULL.
+ * @init_data: user data to pass to @init.
+ *
+ * Recursively refines the tree starting from @root. Each leaf of the
+ * tree is tested for refinement using the @refine function. The new
+ * refined cells created are initialized using @init (if not %NULL)
+ * and are themselves recursively refined.  
+ */
+void ftt_cell_refine (FttCell * root,
+		      FttCellRefineFunc refine,
+		      gpointer refine_data,
+		      FttCellInitFunc init,
+		      gpointer init_data)
+{
+  guint n;
+  FttOct * oct;
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (refine != NULL);
+
+  if (FTT_CELL_IS_LEAF (root) && !(* refine) (root, refine_data))
+    return;
+
+  if (FTT_CELL_IS_LEAF (root))
+    oct_new (root, TRUE, init, init_data);
+
+  g_assert (!FTT_CELL_IS_DESTROYED (root));
+  oct = root->children;
+  for (n = 0; n < FTT_CELLS; n++)
+    if (!FTT_CELL_IS_DESTROYED (&(oct->cell[n])))
+      ftt_cell_refine (&(oct->cell[n]), refine, refine_data, init, init_data);
+}
+
+/**
+ * ftt_cell_draw:
+ * @cell: a #FttCell.
+ * @fp: a file pointer.
+ *
+ * Outputs in @fp an OOGL (geomview) representation of @cell.  
+ */
+void ftt_cell_draw (const FttCell * cell, FILE * fp)
+{
+  gdouble size;
+  FttVector p;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+
+  size = ftt_cell_size (cell)/2.;
+  ftt_cell_pos (cell, &p);
+  fprintf (fp, 
+	   "OFF 8 6 12\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n",
+	   p.x - size, p.y - size, p.z - size,
+	   p.x + size, p.y - size, p.z - size,
+	   p.x + size, p.y + size, p.z - size,
+	   p.x - size, p.y + size, p.z - size,
+	   p.x - size, p.y - size, p.z + size,
+	   p.x + size, p.y - size, p.z + size,
+	   p.x + size, p.y + size, p.z + size,
+	   p.x - size, p.y + size, p.z + size);
+  fputs ("4 3 2 1 0\n"
+	 "4 4 5 6 7\n"
+	 "4 2 3 7 6\n"
+	 "4 0 1 5 4\n"
+	 "4 0 4 7 3\n"
+	 "4 1 2 6 5\n",
+	 fp);
+}
+
+/**
+ * ftt_face_draw:
+ * @face: a #FttCellFace.
+ * @fp: a file pointer.
+ *
+ * Outputs in @fp an OOGL (geomview) representation of @face.  
+ */
+void ftt_face_draw (const FttCellFace * face, FILE * fp)
+{
+  gdouble size;
+  FttVector p;
+#if FTT_2D
+  static FttVector dp[FTT_NEIGHBORS][2] = {
+    {{1.,-1.,0.},{1.,1.,0.}},
+    {{-1.,1.,0.},{-1.,-1,0.}},
+    {{1.,1.,0.},{-1.,1.,0.}},
+    {{-1.,-1.,0.},{1.,-1.,0.}}
+  };
+#else  /* FTT_3D || FTT_2D3 */
+  static FttVector dp[FTT_NEIGHBORS][4] = {
+    {{1.,-1.,1.},{1.,-1.,-1.},{1.,1.,-1.},{1.,1.,1.}},
+    {{-1.,-1.,1.},{-1.,-1.,-1.},{-1.,1.,-1.},{-1.,1.,1.}},
+    {{1.,1.,1.},{1.,1.,-1.},{-1,1.,-1.},{-1.,1.,1.}},
+    {{1.,-1.,1.},{1.,-1.,-1.},{-1,-1.,-1.},{-1.,-1.,1.}},
+    {{1.,-1.,1.},{1.,1.,1.},{-1.,1.,1.},{-1.,-1.,1.}},
+    {{1.,-1.,-1.},{1.,1.,-1.},{-1.,1.,-1.},{-1.,-1.,-1.}},
+  };
+#endif /* FTT_3D ||  FTT_2D3 */
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (fp != NULL);
+
+  size = ftt_cell_size (face->cell)/2.;
+  ftt_cell_pos (face->cell, &p);
+#if FTT_2D
+  fprintf (fp, "VECT 1 2 0 2 0 %g %g 0 %g %g 0\n",
+	   p.x + dp[face->d][0].x*size, 
+	   p.y + dp[face->d][0].y*size,
+	   p.x + dp[face->d][1].x*size, 
+	   p.y + dp[face->d][1].y*size);
+#else /* FTT_3D ||  FTT_2D3 */
+  fprintf (fp, 
+	   "OFF 4 1 4 "
+	   "%g %g %g "
+	   "%g %g %g "
+	   "%g %g %g "
+	   "%g %g %g "
+	   "4 0 1 2 3\n",
+	   p.x + dp[face->d][0].x*size,
+	   p.y + dp[face->d][0].y*size,
+	   p.z + dp[face->d][0].z*size,
+	   p.x + dp[face->d][1].x*size,
+	   p.y + dp[face->d][1].y*size,
+	   p.z + dp[face->d][1].z*size,
+	   p.x + dp[face->d][2].x*size,
+	   p.y + dp[face->d][2].y*size,
+	   p.z + dp[face->d][2].z*size,
+	   p.x + dp[face->d][3].x*size,
+	   p.y + dp[face->d][3].y*size,
+	   p.z + dp[face->d][3].z*size);
+#endif /* FTT_3D ||  FTT_2D3 */
+}
+
+static gdouble coords[FTT_CELLS][3] =
+#if (FTT_2D || FTT_2D3)
+ {{-1., 1.,0.},
+  { 1., 1.,0.},
+  {-1.,-1.,0.},
+  { 1.,-1.,0.}};
+#else  /* FTT_3D */
+ {{-1., 1., 1.},
+  { 1., 1., 1.},
+  {-1.,-1., 1.},
+  { 1.,-1., 1.},
+  {-1., 1.,-1.},
+  { 1., 1.,-1.},
+  {-1.,-1.,-1.},
+  { 1.,-1.,-1.}};
+#endif /* FTT_3D */
+
+/**
+ * ftt_cell_relative_pos:
+ * @cell: a #FttCell (not a root cell).
+ * @pos: a #FttVector.
+ *
+ * Fills @pos with the coordinates of the center of @cell relative to
+ * the center of its parent cell. The length unit is the size of the
+ * parent cell.
+ */
+void ftt_cell_relative_pos (const FttCell * cell,
+			    FttVector * pos)
+{
+  guint n;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (pos != NULL);
+  g_return_if_fail (!FTT_CELL_IS_ROOT (cell));
+
+  n = FTT_CELL_ID (cell);
+  pos->x = coords[n][0]/4.;
+  pos->y = coords[n][1]/4.;
+  pos->z = coords[n][2]/4.;
+}
+
+/**
+ * ftt_cell_pos:
+ * @cell: a #FttCell.
+ * @pos: a #FttVector.
+ *
+ * Fills @pos with the coordinates of the center of @cell.  
+ */
+void ftt_cell_pos (const FttCell * cell, 
+		   FttVector * pos)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (pos != NULL);
+
+  if (FTT_CELL_IS_ROOT (cell))
+    *pos = FTT_ROOT_CELL (cell)->pos;
+  else {
+    gdouble size;
+    guint n;
+
+    size = ftt_cell_size (cell)/2.;
+    n = FTT_CELL_ID (cell);
+    pos->x = cell->parent->pos.x + coords[n][0]*size;
+    pos->y = cell->parent->pos.y + coords[n][1]*size;
+    pos->z = cell->parent->pos.z + coords[n][2]*size;
+  }
+}
+
+/**
+ * ftt_corner_relative_pos:
+ * @cell: a #FttCell.
+ * @d: a set of perpendicular directions.
+ * @pos: a #FttVector.
+ *
+ * Fills @pos with the coordinates (normalised by the size of @cell)
+ * of the corner of @cell defined by @d relative to the position of
+ * the center of @cell.
+ */
+void ftt_corner_relative_pos (const FttCell * cell,
+			      FttDirection d[FTT_DIMENSION],
+			      FttVector * pos)
+{
+  static gdouble coords[FTT_NEIGHBORS][3] =
+#if FTT_2D
+    {{0.5,0.,0.},{-0.5,0.,0.},{0.,0.5,0.},{0.,-0.5,0.}};
+#else  /* FTT_3D || FTT_2D3 */
+    {{0.5,0.,0.},{-0.5,0.,0.},{0.,0.5,0.},{0.,-0.5,0.},{0.,0.,0.5},{0.,0.,-0.5}};
+#endif /* FTT_3D || FTT_2D3 */
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (pos != NULL);
+
+#if FTT_2D
+  pos->x = coords[d[0]][0] + coords[d[1]][0];
+  pos->y = coords[d[0]][1] + coords[d[1]][1];
+  pos->z = 0.;
+#else  /* FTT_3D || FTT_2D3 */
+  pos->x = coords[d[0]][0] + coords[d[1]][0] + coords[d[2]][0];
+  pos->y = coords[d[0]][1] + coords[d[1]][1] + coords[d[2]][1];
+  pos->z = coords[d[0]][2] + coords[d[1]][2] + coords[d[2]][2];
+#endif /* FTT_3D || FTT_2D3 */
+}
+
+/**
+ * ftt_corner_pos:
+ * @cell: a #FttCell.
+ * @d: a set of perpendicular directions.
+ * @pos: a #FttVector.
+ *
+ * Fills @pos with the coordinates of the corner of @cell defined by
+ * @d.
+ */
+void ftt_corner_pos (const FttCell * cell,
+		     FttDirection d[FTT_DIMENSION],
+		     FttVector * pos)
+{
+  gdouble size;
+  FttVector p;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (pos != NULL);
+
+  ftt_corner_relative_pos (cell, d, pos);
+  ftt_cell_pos (cell, &p);
+  size = ftt_cell_size (cell);
+  pos->x = p.x + size*pos->x;
+  pos->y = p.y + size*pos->y;
+  pos->z = p.z + size*pos->z;
+}
+
+/**
+ * ftt_face_pos:
+ * @face: a #FttCellFace.
+ * @pos: a #FttVector.
+ *
+ * Fills @pos with the coordinates of the center of @face.
+ */
+void ftt_face_pos (const FttCellFace * face, FttVector * pos)
+{
+  gdouble size;
+  static gdouble coords[FTT_NEIGHBORS][3] =
+#if FTT_2D
+  {{1.,0.,0.},{-1.,0.,0.},{0.,1.,0.},{0.,-1.,0.}};
+#else  /* FTT_3D || FTT_2D3 */
+  {{1.,0.,0.},{-1.,0.,0.},{0.,1.,0.},{0.,-1.,0.},{0.,0.,1.},{0.,0.,-1.}};
+#endif /* FTT_3D || FTT_2D3 */
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (pos != NULL);
+
+  ftt_cell_pos (face->cell, pos);
+  size = ftt_cell_size (face->cell)/2.;
+  pos->x += size*coords[face->d][0];
+  pos->y += size*coords[face->d][1];
+  pos->z += size*coords[face->d][2];
+}
+
+static void update_children_pos (FttCell * parent)
+{
+  if (!FTT_CELL_IS_LEAF (parent)) {
+    FttOct * oct = parent->children;
+    guint n;
+
+    ftt_cell_pos (parent, &(oct->pos));
+    for (n = 0; n < FTT_CELLS; n++)
+      if (!FTT_CELL_IS_DESTROYED (&(oct->cell[n])))
+	update_children_pos (&(oct->cell[n]));
+  }
+}
+
+/**
+ * ftt_cell_set_pos:
+ * @root: a #FttCell, root of a cell tree.
+ * @pos: a #FttVector.
+ *
+ * Sets the position of the center of the @root cell of a cell tree to
+ * @pos. Updates the positions of its children recursively.  
+ */
+void ftt_cell_set_pos (FttCell * root,
+		       const FttVector * pos)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (root));
+  g_return_if_fail (pos != NULL);
+
+  FTT_ROOT_CELL (root)->pos = *pos;
+  update_children_pos (root);
+}
+
+static void update_children_level (FttCell * parent)
+{
+  if (!FTT_CELL_IS_LEAF (parent)) {
+    FttOct * oct = parent->children;
+    guint n;
+
+    oct->level = ftt_cell_level (parent);
+    for (n = 0; n < FTT_CELLS; n++)
+      if (!FTT_CELL_IS_DESTROYED (&(oct->cell[n])))
+	update_children_level (&(oct->cell[n]));
+  }
+}
+
+/**
+ * ftt_cell_set_level:
+ * @root: a #FttCell, root of a cell tree.
+ * @level: the new level.
+ *
+ * Sets the level of the @root cell of a cell tree to @level.
+ * Updates the levels of its children recursively.  
+ */
+void ftt_cell_set_level (FttCell * root, guint level)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (root));
+
+  FTT_ROOT_CELL (root)->level = level;
+  update_children_level (root);
+}
+
+static void update_neighbor (FttCell * cell,
+			     FttDirection d,
+			     FttCellInitFunc init,
+			     gpointer init_data)
+{
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCell * neighbor = ftt_cell_neighbor_not_cached (cell, d);
+    
+    if (neighbor) {
+      FttOct * oct = cell->children;
+      FttCellChildren children;
+      guint i, n;
+
+      g_assert (oct->neighbors.c[d] == NULL ||
+		oct->neighbors.c[d] == neighbor);
+      oct->neighbors.c[d] = neighbor;
+      
+      if (ftt_cell_level (neighbor) < oct->level) {
+	oct_new (neighbor, TRUE, init, init_data);
+	oct->neighbors.c[d] = ftt_cell_neighbor (cell, d);
+      }
+      
+      g_assert (ftt_cell_level (oct->neighbors.c[d]) == oct->level);
+      n = ftt_cell_children_direction (cell, d, &children);
+      for (i = 0; i < n; i++)
+	if (children.c[i])
+	  update_neighbor (children.c[i], d, init, init_data);
+    }
+  }
+}
+
+/**
+ * ftt_cell_set_neighbor:
+ * @root: a #FttCell, root of a cell tree.
+ * @neighbor: a #FttCell, root of a cell tree.
+ * @d: a direction.
+ * @init: a #FttCellInitFunc or %NULL.
+ * @init_data: user data to pass to @init.
+ * 
+ * Sets the cell tree defined by @neighbor as the neighbor in
+ * direction @d of the cell tree defined by @root.
+ *
+ * Any new cell created during the process is initialized using the
+ * user-defined function @init.
+ *
+ * Both @root and @neighbor must be the roots of their respective cell
+ * trees.  
+ */
+void ftt_cell_set_neighbor (FttCell * root,
+			    FttCell * neighbor,
+			    FttDirection d,
+			    FttCellInitFunc init,
+			    gpointer init_data)
+{
+  FttDirection od;
+
+  g_return_if_fail (d < FTT_NEIGHBORS);
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (root));
+
+  g_return_if_fail (neighbor != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (neighbor));
+
+  g_return_if_fail (ftt_cell_level (root) == ftt_cell_level (neighbor));
+
+  g_return_if_fail (FTT_ROOT_CELL (root)->neighbors.c[d] == NULL);
+  FTT_ROOT_CELL (root)->neighbors.c[d] = neighbor;
+  update_neighbor (root, d, init, init_data);
+
+  od = FTT_OPPOSITE_DIRECTION (d);
+  g_return_if_fail (FTT_ROOT_CELL (neighbor)->neighbors.c[od] == NULL);
+  FTT_ROOT_CELL (neighbor)->neighbors.c[od] = root;
+  update_neighbor (neighbor, od, init, init_data);
+}
+
+static void update_neighbor_match (FttCell * cell,
+				   FttDirection d,
+				   FttCellInitFunc init,
+				   gpointer init_data)
+{
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCell * neighbor = ftt_cell_neighbor_not_cached (cell, d);
+    
+    if (neighbor) {
+      FttOct * oct = cell->children;
+      FttCellChildren children;
+      guint i, n;
+
+      oct->neighbors.c[d] = neighbor;
+      
+      if (ftt_cell_level (neighbor) < oct->level) {
+	oct_new (neighbor, TRUE, init, init_data);
+	oct->neighbors.c[d] = ftt_cell_neighbor (cell, d);
+      }
+      else if (FTT_CELL_IS_LEAF (neighbor))
+	oct_new (neighbor, TRUE, init, init_data);
+      
+      g_assert (ftt_cell_level (oct->neighbors.c[d]) == oct->level);
+      n = ftt_cell_children_direction (cell, d, &children);
+      for (i = 0; i < n; i++)
+	if (children.c[i])
+	  update_neighbor_match (children.c[i], d, init, init_data);
+    }
+  }
+  else { /* leaf cell */
+    FttCell * neighbor = ftt_cell_neighbor_not_cached (cell, d);
+    
+    if (neighbor) {
+      g_assert (ftt_cell_level (cell) == ftt_cell_level (neighbor));
+      if (!FTT_CELL_IS_LEAF (neighbor)) {
+	FttCellChildren children;
+	guint i, n;
+
+	oct_new (cell, TRUE, init, init_data);
+	n = ftt_cell_children_direction (cell, d, &children);
+	for (i = 0; i < n; i++)
+	  if (children.c[i])
+	    update_neighbor_match (children.c[i], d, init, init_data);
+      }
+    }
+  }
+}
+
+/**
+ * ftt_cell_set_neighbor_match:
+ * @root: a #FttCell, root of a cell tree.
+ * @neighbor: a #FttCell, root of a cell tree.
+ * @d: a direction.
+ * @init: a #FttCellInitFunc or %NULL.
+ * @init_data: user data to pass to @init.
+ * 
+ * Sets the cell tree defined by @neighbor as the neighbor in
+ * direction @d of the cell tree defined by @root.
+ *
+ * The boundary between both trees is matched i.e. the type of the
+ * face between any pair of cells belonging to each tree is always
+ * %FTT_FINE_FINE. Any new cell created during the process is
+ * initialized using the user-defined function @init.
+ *
+ * Both @root and @neighbor must be the roots of their respective cell
+ * trees.
+ */
+void ftt_cell_set_neighbor_match (FttCell * root,
+				  FttCell * neighbor,
+				  FttDirection d,
+				  FttCellInitFunc init,
+				  gpointer init_data)
+{
+  FttDirection od;
+
+  g_return_if_fail (d < FTT_NEIGHBORS);
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (root));
+
+  g_return_if_fail (neighbor != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (neighbor));
+
+  g_return_if_fail (ftt_cell_level (root) == ftt_cell_level (neighbor));
+
+  FTT_ROOT_CELL (root)->neighbors.c[d] = neighbor;
+  update_neighbor_match (root, d, init, init_data);
+
+  od = FTT_OPPOSITE_DIRECTION (d);
+  FTT_ROOT_CELL (neighbor)->neighbors.c[od] = root;
+  update_neighbor_match (neighbor, od, init, init_data);
+}
+
+static void cell_traverse_pre_order_all (FttCell * cell,
+					 gint max_depth,
+					 FttCellTraverseFunc func,
+					 gpointer data)
+{
+  FttCell * parent;
+
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  parent = ftt_cell_parent (cell);
+  (* func) (cell, data);
+  /* check that cell has not been deallocated by @func */
+  g_assert (parent == NULL || parent->children != NULL);
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_pre_order_all (c, max_depth, func, data);
+    }
+  }
+}
+
+static void cell_traverse_post_order_all (FttCell * cell,
+					  gint max_depth,
+					  FttCellTraverseFunc func,
+					  gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_post_order_all (c, max_depth, func, data);
+    }
+  }
+
+  (* func) (cell, data);
+}
+
+static void cell_traverse_leafs (FttCell * cell,
+				 gint max_depth,
+				 FttCellTraverseFunc func,
+				 gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_leafs (c, max_depth, func, data);
+    }
+  }
+}
+
+static void cell_traverse_pre_order_nonleafs (FttCell * cell,
+					      gint max_depth,
+					      FttCellTraverseFunc func,
+					      gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCell * parent = ftt_cell_parent (cell);
+
+    (* func) (cell, data);
+    /* check that cell has not been deallocated by @func */
+    g_assert (parent == NULL || parent->children != NULL);
+    if (!FTT_CELL_IS_LEAF (cell)) {
+      FttOct * children = cell->children;
+      guint n;
+
+      for (n = 0; n < FTT_CELLS; n++) {
+	FttCell * c = &(children->cell[n]);
+	
+	if (!FTT_CELL_IS_DESTROYED (c))
+	  cell_traverse_pre_order_nonleafs (c, max_depth, func, data);
+      }
+    }
+  }
+}
+
+static void cell_traverse_post_order_nonleafs (FttCell * cell,
+					       gint max_depth,
+					       FttCellTraverseFunc func,
+					       gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_post_order_nonleafs (c, max_depth, func, data);
+    }
+
+    (* func) (cell, data);
+  }
+}
+
+static void cell_traverse_level (FttCell * cell,
+				 gint max_depth,
+				 FttCellTraverseFunc func,
+				 gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth)
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_level (c, max_depth, func, data);
+    }
+  }
+}
+
+static void cell_traverse_level_leafs (FttCell * cell,
+				       gint max_depth,
+				       FttCellTraverseFunc func,
+				       gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth || FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_level_leafs (c, max_depth, func, data);
+    }
+  }
+}
+
+static void cell_traverse_level_non_leafs (FttCell * cell,
+					   gint max_depth,
+					   FttCellTraverseFunc func,
+					   gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth && !FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_level_non_leafs (c, max_depth, func, data);
+    }
+  }
+}
+
+/**
+ * ftt_cell_traverse:
+ * @root: the root #FttCell of the tree to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell visited.  
+ */
+void ftt_cell_traverse (FttCell * root,
+			FttTraverseType order,
+			FttTraverseFlags flags,
+			gint max_depth,
+			FttCellTraverseFunc func,
+			gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (func != NULL);
+
+  if (max_depth >= 0 && ftt_cell_level (root) > max_depth)
+    return;
+
+  if (flags == FTT_TRAVERSE_ALL) {
+    if (order == FTT_PRE_ORDER)
+      cell_traverse_pre_order_all (root, max_depth, func, data);
+    else
+      cell_traverse_post_order_all (root, max_depth, func, data);
+  }
+  else if ((flags & FTT_TRAVERSE_LEVEL) != 0) {
+    if ((flags & FTT_TRAVERSE_LEAFS) != 0)
+      cell_traverse_level_leafs (root, max_depth, func, data);
+    else if ((flags & FTT_TRAVERSE_NON_LEAFS) != 0)
+      cell_traverse_level_non_leafs (root, max_depth, func, data);
+    else
+      cell_traverse_level (root, max_depth, func, data);
+  }
+  else if ((flags & FTT_TRAVERSE_LEAFS) != 0)
+    cell_traverse_leafs (root, max_depth, func, data);
+  else {
+    g_return_if_fail ((flags & FTT_TRAVERSE_NON_LEAFS) != 0);
+
+    if (order == FTT_PRE_ORDER)
+      cell_traverse_pre_order_nonleafs (root, max_depth, func, data);
+    else
+      cell_traverse_post_order_nonleafs (root, max_depth, func, data);
+  }
+}
+
+/**
+ * ftt_cell_traverse_condition:
+ * @root: the root #FttCell of the tree to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * @condition: the condition.
+ * @cdata: user data to pass to @condition.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell visited.
+ *
+ * Traversal of any branch of the tree is stopped whenever @condition
+ * is not verified.
+ */
+void ftt_cell_traverse_condition (FttCell * root,
+				  FttTraverseType order,
+				  FttTraverseFlags flags,
+				  gint max_depth,
+				  FttCellTraverseFunc func,
+				  gpointer data,
+				  gboolean (* condition) (FttCell *, gpointer),
+				  gpointer cdata)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (condition != NULL);
+
+  if ((max_depth >= 0 && ftt_cell_level (root) > max_depth) ||
+      !(* condition) (root, cdata))
+    return;
+
+  if (order == FTT_PRE_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (root)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (root))))
+    (* func) (root, data);
+  if (!FTT_CELL_IS_LEAF (root)) {
+    struct _FttOct * children = root->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if (!FTT_CELL_IS_DESTROYED (c))
+	ftt_cell_traverse_condition (c, order, flags, max_depth, func, data, condition, cdata);
+    }
+  }
+  if (order == FTT_POST_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (root)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (root))))
+    (* func) (root, data);
+}
+
+/**
+ * ftt_cell_bbox:
+ * @cell: a #FttCell.
+ * @bb: a #GtsBBox.
+ *
+ * Fills @bb with the bounding box of @cell.
+ */
+void ftt_cell_bbox (const FttCell * cell, GtsBBox * bb)
+{
+  FttVector p;
+  gdouble h;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (bb != NULL);
+  
+  h = ftt_cell_size (cell)/1.99999;
+  ftt_cell_pos (cell, &p);
+  bb->x1 = p.x - h; bb->y1 = p.y - h;
+  bb->x2 = p.x + h; bb->y2 = p.y + h; 
+#if FTT_2D
+  bb->z1 = bb->z2 = 0.;
+#elif FTT_2D3
+  bb->z1 = p.z - 1./1.99999; bb->z2 = p.z + 1./1.99999;
+#else  /* 3D */
+  bb->z1 = p.z - h; bb->z2 = p.z + h;
+#endif /* 3D */
+}
+
+static gboolean cell_is_in_box (FttCell * cell, gpointer data)
+{
+  GtsBBox * box = data;
+  GtsBBox bb;
+
+  ftt_cell_bbox (cell, &bb);
+  return gts_bboxes_are_overlapping (&bb, box);
+}
+
+/**
+ * ftt_cell_traverse_box:
+ * @root: the root #FttCell of the tree to traverse.
+ * @box: a #GtsBBox.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell visited. Only the cells partly or
+ * totally contained within @box are visited.  
+ */
+void ftt_cell_traverse_box (FttCell * root,
+			    GtsBBox * box,
+			    FttTraverseType order,
+			    FttTraverseFlags flags,
+			    gint max_depth,
+			    FttCellTraverseFunc func,
+			    gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (func != NULL);
+
+  ftt_cell_traverse_condition (root, order, flags, max_depth, func, data, cell_is_in_box, box);
+}
+
+static void cell_traverse_boundary_pre_order_all (FttCell * cell,
+						  FttDirection d,
+						  gint max_depth,
+						  FttCellTraverseFunc func,
+						  gpointer data)
+{
+  FttCell * parent;
+
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  parent = ftt_cell_parent (cell);
+  (* func) (cell, data);
+  /* check that cell has not been deallocated by @func */
+  g_assert (parent == NULL || parent->children != NULL);
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_pre_order_all (children.c[i], d, 
+					      max_depth, func, data);
+  }
+}
+
+static void cell_traverse_boundary_post_order_all (FttCell * cell,
+						   FttDirection d,
+						   gint max_depth,
+						   FttCellTraverseFunc func,
+						   gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_post_order_all (children.c[i], d, 
+					       max_depth, func, data);
+  }
+
+  (* func) (cell, data);
+}
+
+static void cell_traverse_boundary_leafs (FttCell * cell,
+					  FttDirection d,
+					  gint max_depth,
+					  FttCellTraverseFunc func,
+					  gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  else {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_leafs (children.c[i], d, 
+				      max_depth, func, data);
+  }
+}
+
+static void cell_traverse_boundary_pre_order_nonleafs (FttCell * cell,
+						       FttDirection d,
+						       gint max_depth,
+				   FttCellTraverseFunc func,
+						       gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCell * parent = ftt_cell_parent (cell);
+
+    (* func) (cell, data);
+    /* check that cell has not been deallocated by @func */
+    g_assert (parent == NULL || parent->children != NULL);
+    if (!FTT_CELL_IS_LEAF (cell)) {
+      FttCellChildren children;
+      guint i, n;
+
+      n = ftt_cell_children_direction (cell, d, &children);
+      for (i = 0; i < n; i++)
+	if (children.c[i])
+	  cell_traverse_boundary_pre_order_nonleafs (children.c[i], d, 
+						     max_depth, func, data);
+    }
+  }
+}
+
+static void cell_traverse_boundary_post_order_nonleafs (FttCell * cell,
+							FttDirection d,
+							gint max_depth,
+				    FttCellTraverseFunc func,
+							gpointer data)
+{
+  if (max_depth >= 0 && ftt_cell_level (cell) > max_depth)
+    return;
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_post_order_nonleafs (children.c[i], d, 
+						    max_depth, func, data);
+    (* func) (cell, data);
+  }
+}
+
+static void cell_traverse_boundary_level (FttCell * cell,
+					  FttDirection d,
+					  gint max_depth,
+					  FttCellTraverseFunc func,
+					  gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth)
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_level (children.c[i], d, 
+				      max_depth, func, data);
+  }
+}
+
+static void cell_traverse_boundary_level_leafs (FttCell * cell,
+						FttDirection d,
+						gint max_depth,
+						FttCellTraverseFunc func,
+						gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth || FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_level_leafs (children.c[i], d, 
+					    max_depth, func, data);
+  }
+}
+
+static void cell_traverse_boundary_level_non_leafs (FttCell * cell,
+						    FttDirection d,
+						    gint max_depth,
+						    FttCellTraverseFunc func,
+						    gpointer data)
+{
+  if (ftt_cell_level (cell) == max_depth && !FTT_CELL_IS_LEAF (cell))
+    (* func) (cell, data);
+  else if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren children;
+    guint i, n;
+
+    n = ftt_cell_children_direction (cell, d, &children);
+    for (i = 0; i < n; i++)
+      if (children.c[i])
+	cell_traverse_boundary_level_non_leafs (children.c[i], d, 
+						max_depth, func, data);
+  }
+}
+
+/**
+ * ftt_cell_traverse_boundary:
+ * @root: the root #FttCell of the tree to traverse.
+ * @d: the direction of the boundary to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ *
+ * Traverses the boundary of a cell tree in direction @d starting at
+ * the given root #FttCell. Calls the given function for each node
+ * visited.  
+ */
+void ftt_cell_traverse_boundary (FttCell * root,
+				 FttDirection d,
+				 FttTraverseType order,
+				 FttTraverseFlags flags,
+				 gint max_depth,
+				 FttCellTraverseFunc func,
+				 gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (d < FTT_NEIGHBORS);
+  g_return_if_fail (func != NULL);
+
+  if (max_depth >= 0 && ftt_cell_level (root) > max_depth)
+    return;
+
+  if (flags == FTT_TRAVERSE_ALL) {
+    if (order == FTT_PRE_ORDER)
+      cell_traverse_boundary_pre_order_all (root, d, max_depth, func, data);
+    else
+      cell_traverse_boundary_post_order_all (root, d, max_depth, func, data);
+  }
+  else if ((flags & FTT_TRAVERSE_LEVEL) != 0) {
+    if ((flags & FTT_TRAVERSE_LEAFS) != 0)
+      cell_traverse_boundary_level_leafs (root, d, max_depth, func, data);
+    else if ((flags & FTT_TRAVERSE_NON_LEAFS) != 0)
+      cell_traverse_boundary_level_non_leafs (root, d, max_depth, func, data);
+    else
+      cell_traverse_boundary_level (root, d, max_depth, func, data);
+  }
+  else if ((flags & FTT_TRAVERSE_LEAFS) != 0)
+    cell_traverse_boundary_leafs (root, d, max_depth, func, data);
+  else {
+    g_return_if_fail ((flags & FTT_TRAVERSE_NON_LEAFS) != 0);
+
+    if (order == FTT_PRE_ORDER)
+      cell_traverse_boundary_pre_order_nonleafs (root, d, 
+						 max_depth, func, data);
+    else
+      cell_traverse_boundary_post_order_nonleafs (root, d, 
+						  max_depth, func, data);
+  }
+}
+
+static void oct_destroy (FttOct * oct,
+			 FttCellCleanupFunc cleanup,
+			 gpointer data)
+{
+  guint n;
+
+  g_return_if_fail (oct != NULL);
+  g_return_if_fail (oct->parent->children == oct);
+
+  oct->parent->children = NULL;
+  for (n = 0; n < FTT_CELLS; n++)
+    ftt_cell_destroy (&(oct->cell[n]), cleanup, data);
+  g_free (oct);
+}
+
+/**
+ * ftt_cell_destroy:
+ * @cell: a #FttCell.
+ * @cleanup: a #FttCellCleanupFunc to call before destroying @cell or %NULL.
+ * @data: user data to pass to @cleanup.
+ *
+ * Frees all memory allocated for @cell and its descendants.
+ *
+ * The user-defined function @cleanup is called prior to freeing memory.
+ */
+void ftt_cell_destroy (FttCell * cell,
+		       FttCellCleanupFunc cleanup,
+		       gpointer data)
+{
+  FttCellNeighbors neighbor;
+  guint i, level;
+
+  g_return_if_fail (cell != NULL);
+
+  if (FTT_CELL_IS_DESTROYED (cell))
+    return;
+
+  ftt_cell_neighbors (cell, &neighbor);
+  level = ftt_cell_level (cell);
+
+  if (cleanup)
+    (* cleanup) (cell, data);
+  cell->flags |= FTT_FLAG_DESTROYED;
+
+  /* destroy children */
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    oct_destroy (cell->children, cleanup, data);
+    cell->children = NULL;
+  }
+
+  /* update relationships for neighbors */
+  for (i = 0; i < FTT_NEIGHBORS; i++)
+    if (neighbor.c[i] && ftt_cell_level (neighbor.c[i]) == level) {
+      FttDirection od = FTT_OPPOSITE_DIRECTION (i);
+
+      if (FTT_CELL_IS_ROOT (neighbor.c[i])) {
+	FttCell * opneighbor = FTT_ROOT_CELL (neighbor.c[i])->neighbors.c[od];
+
+	g_assert (opneighbor == cell);
+	FTT_ROOT_CELL (neighbor.c[i])->neighbors.c[od] = NULL;
+      }
+      if (!FTT_CELL_IS_LEAF (neighbor.c[i]))
+	neighbor.c[i]->children->neighbors.c[od] = NULL;
+    }
+  
+  if (FTT_CELL_IS_ROOT (cell))
+    g_free (cell);
+  else if (!FTT_CELL_IS_LEAF (cell->parent->parent)) {
+    /* if parent Oct is not already destroyed and empty destroy it */
+    FttOct * parent = cell->parent;
+    gboolean empty = TRUE;
+
+    for (i = 0; i < FTT_CELLS && empty; i++)
+      if (!FTT_CELL_IS_DESTROYED (&(parent->cell[i])))
+	empty = FALSE;
+    if (empty)
+      oct_destroy (parent, NULL, NULL);
+  }
+}
+
+/**
+ * ftt_cell_destroy_root:
+ * @root: the root cell of a cell tree.
+ * @children: a #FttCellChildren.
+ * @cleanup: a #FttCellCleanupFunc to call before destroying a cell.
+ * @data: user data to pass to @cleanup.
+ *
+ * Destroys the root cell of a cell tree but not its children. Each
+ * child becomes the root cell of a new cell tree. The new (orphaned)
+ * children are returned in @children.
+ *
+ * Note that the function will fail if @root is also a leaf cell.
+ */
+void ftt_cell_destroy_root (FttCell * root,
+			    FttCellChildren * children,
+			    FttCellCleanupFunc cleanup,
+			    gpointer data)
+{
+  guint i;
+  FttCellNeighbors neighbor;
+  FttCellChildren child;
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (FTT_CELL_IS_ROOT (root));
+  g_return_if_fail (!FTT_CELL_IS_LEAF (root));
+  g_return_if_fail (!FTT_CELL_IS_DESTROYED (root));
+  g_return_if_fail (children != NULL);
+
+  if (cleanup)
+    (* cleanup) (root, data);
+  root->flags |= FTT_FLAG_DESTROYED;
+
+  ftt_cell_neighbors (root, &neighbor);
+  for (i = 0; i < FTT_NEIGHBORS; i++)
+    if (neighbor.c[i]) {
+      FttDirection od = FTT_OPPOSITE_DIRECTION (i);
+      
+      g_assert (FTT_CELL_IS_ROOT (neighbor.c[i]));
+      g_assert (FTT_ROOT_CELL (neighbor.c[i])->neighbors.c[od] == root);
+      FTT_ROOT_CELL (neighbor.c[i])->neighbors.c[od] = NULL;
+
+      if (!FTT_CELL_IS_LEAF (neighbor.c[i]))
+	neighbor.c[i]->children->neighbors.c[od] = NULL;
+    }
+
+  ftt_cell_children (root, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      FttCell * newc;
+      FttDirection d;
+
+      newc = g_malloc0 (sizeof (FttRootCell));
+      newc->data = child.c[i]->data;
+      newc->children = child.c[i]->children;
+      ftt_cell_pos (child.c[i], &FTT_ROOT_CELL (newc)->pos);
+      FTT_ROOT_CELL (newc)->level = ftt_cell_level (child.c[i]);
+      ftt_cell_neighbors (child.c[i], &FTT_ROOT_CELL (newc)->neighbors);
+      g_return_if_fail (!FTT_CELL_IS_LEAF (newc));
+      newc->children->parent = newc;
+      children->c[i] = newc;
+
+      neighbor = FTT_ROOT_CELL (newc)->neighbors;
+      for (d = 0; d < FTT_NEIGHBORS; d++)
+	if (neighbor.c[d]) {
+	  FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+
+	  if (FTT_CELL_IS_ROOT (neighbor.c[d])) {
+	    g_assert (FTT_ROOT_CELL (neighbor.c[d])->neighbors.c[od] 
+		      == child.c[i]);
+	    FTT_ROOT_CELL (neighbor.c[d])->neighbors.c[od] = newc;
+	  }
+	  if (!FTT_CELL_IS_LEAF (neighbor.c[d])) {
+	    g_assert (neighbor.c[d]->children->neighbors.c[od] == child.c[i]);
+	    neighbor.c[d]->children->neighbors.c[od] = newc;
+	  }
+	}
+    }
+    else
+      children->c[i] = NULL;
+
+  g_free (root->children);
+  g_free (root);
+}
+
+/**
+ * ftt_cell_flatten:
+ * @root: the root of the cell tree to flatten.
+ * @d: the direction in which to flatten.
+ * @cleanup: a #FttCellCleanupFunc to call before destroying a cell.
+ * @data: user data to pass to @cleanup.
+ *
+ * Recursively destroys all the cells of the tree defined by @root
+ * which do not form the boundary in direction @d. The resulting cell
+ * tree is in effect a domain "flattened" in direction @d.
+ *
+ * The resulting domain is always one-cell thick in direction @d.  
+ */
+void ftt_cell_flatten (FttCell * root,
+		       FttDirection d,
+		       FttCellCleanupFunc cleanup,
+		       gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (d < FTT_NEIGHBORS);
+
+#if FTT_2D3
+  if (d >= FTT_NEIGHBORS_2D)
+    return;
+#endif /* 2D3 */
+
+  if (!FTT_CELL_IS_LEAF (root)) {
+    struct _FttOct * oct;
+    guint i;
+#if (FTT_2D || FTT_2D3)
+    static gint index[FTT_NEIGHBORS_2D][FTT_CELLS/2] =
+    {{1, 3},
+     {0, 2},
+     {0, 1},
+     {2, 3}};
+#else  /* FTT_3D */
+    static gint index[FTT_NEIGHBORS][FTT_CELLS/2] =
+    {{1, 3, 5, 7},
+     {0, 2, 4, 6},
+     {0, 1, 4, 5},
+     {2, 3, 6, 7},
+     {0, 1, 2, 3},
+     {4, 5, 6, 7}};
+#endif /* FTT_3D */
+    FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+
+    oct = root->children;
+    for (i = 0; i < FTT_CELLS/2; i++) {
+      FttCell * c = &(oct->cell[index[od][i]]);
+      if (!FTT_CELL_IS_DESTROYED (c))
+	ftt_cell_destroy (c, cleanup, data);
+    }
+    if (!FTT_CELL_IS_LEAF (root))
+      for (i = 0; i < FTT_CELLS/2; i++)
+	if (!FTT_CELL_IS_DESTROYED (&(oct->cell[index[d][i]])))
+	  ftt_cell_flatten (&(oct->cell[index[d][i]]), d, cleanup, data);
+  }
+}
+
+/**
+ * ftt_cell_locate:
+ * @root: a #FttCell.
+ * @target: position of the point to look for.
+ * @max_depth: maximum depth to consider (-1 means no restriction, see below for -2).
+ *
+ * Locates the cell of the tree defined by @root containing
+ * @target. This is done efficiently in log(n) operations by using the
+ * topology of the tree.
+ *
+ * If @max_depth is set to -2, the finest cell containing @target is
+ * returned. This cell is not necessarily a leaf-cell in contrast to
+ * the case where @max_depth is set to -1.
+ *
+ * Returns: a #FttCell of the tree defined by @root and
+ * containing (boundary included) the point defined by @target or
+ * %NULL if @target is not contained in any cell of @root.  
+ */
+FttCell * ftt_cell_locate (FttCell * root, 
+			   FttVector target,
+			   gint max_depth)
+{
+  FttVector pos;
+  gdouble size;
+
+  g_return_val_if_fail (root != NULL, NULL);
+
+  ftt_cell_pos (root, &pos);
+  size = ftt_cell_size (root)/2.;
+
+  if (target.x > pos.x + size || target.x < pos.x - size ||
+      target.y > pos.y + size || target.y < pos.y - size
+#if FTT_2D3
+      || target.z > pos.z + 0.5 || target.z < pos.z - 0.5
+#elif !FTT_2D
+      || target.z > pos.z + size || target.z < pos.z - size
+#endif
+      )
+    return NULL;
+
+  do {
+    if (FTT_CELL_IS_LEAF (root) || ftt_cell_level (root) == max_depth)
+      return root;
+#if (FTT_2D || FTT_2D3)
+    static guint index[2][2] = {{2,3},{0,1}};
+    guint n = index[target.y > pos.y][target.x > pos.x];
+#else  /* 3D */
+    static guint index[2][2][2] = {{{6,7},{4,5}},{{2,3},{0,1}}};
+    guint n = index[target.z > pos.z][target.y > pos.y][target.x > pos.x];
+#endif /* 3D */
+    root = &(root->children->cell[n]);
+    size /= 2.;
+    pos.x += coords[n][0]*size;
+    pos.y += coords[n][1]*size;
+#if !(FTT_2D || FTT_2D3)
+    pos.z += coords[n][2]*size;
+#endif /* 3D */
+  } while (!FTT_CELL_IS_DESTROYED (root));
+  return max_depth == -2 ? ftt_cell_parent (root) : NULL;
+}
+
+static void bubble_sort (FttCellChildren * child, gdouble * d)
+{
+  guint i, j;
+
+  for (i = 0; i < FTT_CELLS - 1; i++)
+    for (j = 0; j < FTT_CELLS - 1 - i; j++)
+      if (d[j+1] < d[j]) {
+	gdouble tmp = d[j];
+	FttCell * cell = child->c[j];
+	d[j] = d[j+1];
+	d[j+1] = tmp;
+	child->c[j] = child->c[j+1];
+	child->c[j+1] = cell;
+      }
+}
+
+/**
+ * ftt_cell_point_distance2_min:
+ * @cell: a #FttCell.
+ * @p: a #GtsPoint.
+ * 
+ * Returns: the square of the minimum distance between @cell and @p.
+ */
+gdouble ftt_cell_point_distance2_min (FttCell * cell, GtsPoint * p)
+{
+  GtsBBox bb;
+  gdouble dmin, xd1, xd2, yd1, yd2, zd1, zd2;
+    
+  g_return_val_if_fail (cell != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (p != NULL, G_MAXDOUBLE);
+
+  ftt_cell_bbox (cell, &bb);
+
+  xd1 = (bb.x1 - p->x)*(bb.x1 - p->x);
+  xd2 = (p->x - bb.x2)*(p->x - bb.x2);
+  yd1 = (bb.y1 - p->y)*(bb.y1 - p->y);
+  yd2 = (p->y - bb.y2)*(p->y - bb.y2);
+  zd1 = (bb.z1 - p->z)*(bb.z1 - p->z);
+  zd2 = (p->z - bb.z2)*(p->z - bb.z2);
+  
+  dmin = p->x < bb.x1 ? xd1 : p->x > bb.x2 ? xd2 : 0.0;
+  dmin += p->y < bb.y1 ? yd1 : p->y > bb.y2 ? yd2 : 0.0;
+  dmin += p->z < bb.z1 ? zd1 : p->z > bb.z2 ? zd2 : 0.0;
+
+  return dmin;
+}
+
+void ftt_cell_point_distance2_internal (FttCell * root,
+					GtsPoint * p,
+					gdouble d,
+					gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+					gpointer data,
+					FttCell ** closest,
+					gdouble * dmin)
+{
+  if (FTT_CELL_IS_LEAF (root)) {
+    if (d < *dmin) {
+      *dmin = d;
+      if (closest)
+	*closest = root;
+    }
+  }
+  else {
+    FttCellChildren child;
+    gdouble dc[FTT_CELLS];
+    guint i;
+
+    ftt_cell_children (root, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      dc[i] = child.c[i] ? (* distance2) (child.c[i], p, data) : G_MAXDOUBLE;
+    bubble_sort (&child, dc);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (dc[i] < *dmin)
+	ftt_cell_point_distance2_internal (child.c[i], p, dc[i], distance2, data, closest, dmin);
+  }
+}
+
+/**
+ * ftt_cell_point_distance2:
+ * @root: a #FttCell.
+ * @p: a #GtsPoint.
+ * @distance2: the squared distance function.
+ * @data: user data to pass to @distance2.
+ * @closest: where to return the closest cell or %NULL.
+ *
+ * For non-leafs cells @distance2 must return a lower-bound for the
+ * minimum distance (using for example ftt_cell_point_distance2_min()).
+ *
+ * Returns: the square of the minimum distance measured according to
+ * @distance2 between @p and a leaf cell of @root.
+ */
+gdouble ftt_cell_point_distance2 (FttCell * root,
+				  GtsPoint * p,
+				  gdouble (* distance2) (FttCell *, GtsPoint *, gpointer),
+				  gpointer data,
+				  FttCell ** closest)
+{
+  gdouble d, dmin = G_MAXDOUBLE;
+
+  g_return_val_if_fail (root != NULL, dmin);
+  g_return_val_if_fail (p != NULL, dmin);
+  g_return_val_if_fail (distance2 != NULL, dmin);
+
+  if (closest)
+    *closest = NULL;
+  d = (* distance2) (root, p, data);
+  if (d < dmin)
+    ftt_cell_point_distance2_internal (root, p, d, distance2, data, closest, &dmin);
+  return dmin;
+}
+
+/**
+ * ftt_cell_depth:
+ * @root: a #FttCell.
+ *
+ * Returns: the depth of the tree starting at @root, i.e. the maximum
+ * level of any cell descendant of @root.  
+ */
+guint ftt_cell_depth (const FttCell * root)
+{
+  guint depth;
+
+  g_return_val_if_fail (root != NULL, 0);
+
+  depth = ftt_cell_level (root);
+  if (root->children) {
+    FttOct * oct = root->children;
+    guint n;
+    
+    for (n = 0; n < FTT_CELLS; n++) 
+      if (!FTT_CELL_IS_DESTROYED (&(oct->cell[n]))) {
+	guint d = ftt_cell_depth (&(oct->cell[n]));
+	if (d > depth)
+	  depth = d;
+      }
+  }
+  return depth;
+}
+
+/**
+ * ftt_cell_write:
+ * @root: a #FttCell.
+ * @max_depth: the maximum depth at which to stop writing (-1 means no limit).
+ * @fp: a file pointer.
+ * @write: a #FttCellWriteFunc function or %NULL.
+ * @data: user data to pass to @write.
+ *
+ * Writes in the file pointed to by @fp a text representation of the
+ * cell tree starting at @root. If not %NULL, the user-defined
+ * function @write is used to write the extra user data associated
+ * with each cell.  
+ */
+void ftt_cell_write (const FttCell * root,
+		     gint max_depth,
+		     FILE * fp,
+		     FttCellWriteFunc write,
+		     gpointer data)
+{
+  guint flags;
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (fp != NULL);
+
+  flags = root->flags;
+  if (FTT_CELL_IS_LEAF (root) || ftt_cell_level (root) == max_depth)
+    flags |= FTT_FLAG_LEAF;
+
+  fprintf (fp, "%u", flags);
+  if (write && !FTT_CELL_IS_DESTROYED (root))
+    (* write) (root, fp, data);
+  fputc ('\n', fp);
+
+  if ((flags & FTT_FLAG_LEAF) == 0) {
+    FttOct * oct;
+    guint i;
+
+    oct = root->children;
+    for (i = 0; i < FTT_CELLS; i++)
+      ftt_cell_write (&(oct->cell[i]), max_depth, fp, write, data);
+  }
+}
+
+/**
+ * ftt_cell_write_binary:
+ * @root: a #FttCell.
+ * @max_depth: the maximum depth at which to stop writing (-1 means no limit).
+ * @fp: a file pointer.
+ * @write: a #FttCellWriteFunc function or %NULL.
+ * @data: user data to pass to @write.
+ *
+ * Writes in the file pointed to by @fp a binary representation of the
+ * cell tree starting at @root. If not %NULL, the user-defined
+ * function @write is used to write the extra user data associated
+ * with each cell.  
+ */
+void ftt_cell_write_binary (const FttCell * root,
+			    gint max_depth,
+			    FILE * fp,
+			    FttCellWriteFunc write,
+			    gpointer data)
+{
+  guint flags;
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (fp != NULL);
+
+  flags = root->flags;
+  if (FTT_CELL_IS_LEAF (root) || ftt_cell_level (root) == max_depth)
+    flags |= FTT_FLAG_LEAF;
+
+  fwrite (&flags, sizeof (guint), 1, fp);
+  if (write && !FTT_CELL_IS_DESTROYED (root))
+    (* write) (root, fp, data);
+
+  if ((flags & FTT_FLAG_LEAF) == 0) {
+    FttOct * oct;
+    guint i;
+
+    oct = root->children;
+    for (i = 0; i < FTT_CELLS; i++)
+      ftt_cell_write_binary (&(oct->cell[i]), max_depth, fp, write, data);
+  }
+}
+
+#define FTT_CELL_IS_FLAGGED_LEAF(cell) (((cell)->flags & FTT_FLAG_LEAF) != 0)
+
+static gboolean oct_read (FttCell * parent, 
+			  GtsFile * fp,
+			  FttCellReadFunc read,
+			  gpointer data);
+
+static gboolean cell_read (FttCell * cell, 
+			   GtsFile * fp,
+			   FttCellReadFunc read,
+			   gpointer data)
+{
+  guint flags;
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (flags)");
+    return FALSE;
+  }
+  flags = atoi (fp->token->str);
+  if (FTT_CELL_ID (cell) != (flags & FTT_FLAG_ID)) {
+    gts_file_error (fp, "FTT_CELL_ID (cell) `%d' != (flags & FTT_FLAG_ID) `%d'",
+		    FTT_CELL_ID (cell), (flags & FTT_FLAG_ID));
+    return FALSE;
+  }
+  cell->flags = flags;
+
+  gts_file_next_token (fp);
+  if (fp->type != '\n' && read && !FTT_CELL_IS_DESTROYED (cell))
+    (* read) (cell, fp, data);
+  if (fp->type == GTS_ERROR)
+    return FALSE;
+  gts_file_first_token_after (fp, '\n');
+
+  if (!FTT_CELL_IS_DESTROYED (cell) && !FTT_CELL_IS_FLAGGED_LEAF (cell))
+    return oct_read (cell, fp, read, data);
+
+  cell->flags &= ~FTT_FLAG_LEAF;
+  return TRUE;
+}
+
+static gboolean oct_read (FttCell * parent,
+			  GtsFile * fp,
+			  FttCellReadFunc read,
+			  gpointer data)
+{
+  FttOct * oct;
+  guint n;
+
+  oct = g_malloc0 (sizeof (FttOct));
+  oct->level = ftt_cell_level (parent);
+  oct->parent = parent;
+#ifdef FTT_2D3
+  oct->dz = ftt_cell_dz (parent);
+#endif
+  parent->children = oct;
+  ftt_cell_pos (parent, &(oct->pos));
+  
+  for (n = 0; n < FTT_CELLS; n++) {
+    oct->cell[n].parent = oct;
+    oct->cell[n].flags = n;
+  }
+
+  for (n = 0; n < FTT_CELLS; n++)
+    if (!cell_read (&(oct->cell[n]), fp, read, data))
+      return FALSE;
+  
+  return TRUE;
+}
+
+static void set_neighbors (FttCell * cell)
+{
+  ftt_cell_neighbors (cell, &(cell->children->neighbors));
+}
+
+/**
+ * ftt_cell_read:
+ * @fp: a #GtsFile.
+ * @read: a #FttCellReadFunc function or %NULL.
+ * @data: user data to pass to @read.
+ *
+ * If an error occurs (i.e. corrupted file or file format incorrect),
+ * the @error field of @fp is set. A possibly incomplete tree is then
+ * returned.
+ *
+ * Returns: the root cell of the tree contained in the file pointed to
+ * by @fp. If not %NULL, the user-defined function @read is used to
+ * read the extra user data associated with each cell.  
+ */
+FttCell * ftt_cell_read (GtsFile * fp,
+			 FttCellReadFunc read,
+			 gpointer data)
+{
+  FttCell * root;
+  guint l, depth;
+
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  root = ftt_cell_new (NULL, NULL);
+  cell_read (root, fp, read, data);
+
+  depth = ftt_cell_depth (root);
+  for (l = 0; l < depth; l++)
+    ftt_cell_traverse (root, FTT_PRE_ORDER, 
+		       FTT_TRAVERSE_LEVEL|FTT_TRAVERSE_NON_LEAFS, l, 
+		       (FttCellTraverseFunc) set_neighbors, NULL);
+
+  return root;
+}
+
+static gboolean oct_read_binary (FttCell * parent, 
+				 GtsFile * fp,
+				 FttCellReadFunc read,
+				 gpointer data);
+
+static gboolean cell_read_binary (FttCell * cell, 
+				  GtsFile * fp,
+				  FttCellReadFunc read,
+				  gpointer data)
+{
+  guint flags;
+
+  if (gts_file_read (fp, &flags, sizeof (guint), 1) != 1) {
+    gts_file_error (fp, "expecting an integer (flags)");
+    return FALSE;
+  }
+  if (FTT_CELL_ID (cell) != (flags & FTT_FLAG_ID)) {
+    gts_file_error (fp, "FTT_CELL_ID (cell) `%d' != (flags & FTT_FLAG_ID) `%d'",
+		    FTT_CELL_ID (cell), (flags & FTT_FLAG_ID));
+    return FALSE;
+  }
+  cell->flags = flags;
+
+  if (read && !FTT_CELL_IS_DESTROYED (cell))
+    (* read) (cell, fp, data);
+  if (fp->type == GTS_ERROR)
+    return FALSE;
+
+  if (!FTT_CELL_IS_DESTROYED (cell) && !FTT_CELL_IS_FLAGGED_LEAF (cell))
+    return oct_read_binary (cell, fp, read, data);
+
+  cell->flags &= ~FTT_FLAG_LEAF;
+  return TRUE;
+}
+
+static gboolean oct_read_binary (FttCell * parent,
+				 GtsFile * fp,
+				 FttCellReadFunc read,
+				 gpointer data)
+{
+  FttOct * oct;
+  guint n;
+
+  oct = g_malloc0 (sizeof (FttOct));
+  oct->level = ftt_cell_level (parent);
+  oct->parent = parent;
+#ifdef FTT_2D3
+  oct->dz = ftt_cell_dz (parent);
+#endif
+  parent->children = oct;
+  ftt_cell_pos (parent, &(oct->pos));
+  
+  for (n = 0; n < FTT_CELLS; n++) {
+    oct->cell[n].parent = oct;
+    oct->cell[n].flags = n;
+  }
+
+  for (n = 0; n < FTT_CELLS; n++)
+    if (!cell_read_binary (&(oct->cell[n]), fp, read, data))
+      return FALSE;
+  
+  return TRUE;
+}
+
+/**
+ * ftt_cell_read_binary:
+ * @fp: a #GtsFile.
+ * @read: a #FttCellReadFunc function or %NULL.
+ * @data: user data to pass to @read.
+ *
+ * If an error occurs (i.e. corrupted file or file format incorrect),
+ * the @error field of @fp is set. A possibly incomplete tree is then
+ * returned.
+ *
+ * Returns: the root cell of the tree contained in the file pointed to
+ * by @fp. If not %NULL, the user-defined function @read is used to
+ * read the extra user data associated with each cell.  
+ */
+FttCell * ftt_cell_read_binary (GtsFile * fp,
+				FttCellReadFunc read,
+				gpointer data)
+{
+  FttCell * root;
+  guint l, depth;
+
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  root = ftt_cell_new (NULL, NULL);
+  cell_read_binary (root, fp, read, data);
+
+  depth = ftt_cell_depth (root);
+  for (l = 0; l < depth; l++)
+    ftt_cell_traverse (root, FTT_PRE_ORDER, 
+		       FTT_TRAVERSE_LEVEL|FTT_TRAVERSE_NON_LEAFS, l, 
+		       (FttCellTraverseFunc) set_neighbors, NULL);
+
+  return root;
+}
+
+/**
+ * ftt_refine_corner:
+ * @cell: a #FttCell.
+ *
+ * Returns: %TRUE if @cell is a leaf and if any of its "corner"
+ * neighbors are more than one level more refined, %FALSE otherwise
+ * (see figure topology.fig). 
+ */
+gboolean ftt_refine_corner (const FttCell * cell)
+{
+  FttCellNeighbors neighbor;
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+
+  if (!FTT_CELL_IS_LEAF (cell))
+    return FALSE;
+
+  ftt_cell_neighbors (cell, &neighbor);
+#if FTT_2D3
+  for (i = 0; i < FTT_NEIGHBORS_2D; i++) {
+#else
+  for (i = 0; i < FTT_NEIGHBORS; i++) {
+#endif
+    FttCell * n = neighbor.c[i];
+
+    if (n && !FTT_CELL_IS_LEAF (n)) {
+      FttCellChildren child;
+      guint j, k;
+
+      k = ftt_cell_children_direction (n, FTT_OPPOSITE_DIRECTION (i), &child);
+      for (j = 0; j < k; j++) {
+	FttCell * c = child.c[j];
+
+	if (c) {
+#if (FTT_2D || FTT_2D3)
+	  static guint perpendicular[FTT_NEIGHBORS_2D][FTT_CELLS/2] =
+	  {{2,3},
+	   {2,3},
+	   {1,0},
+	   {1,0}};
+	  FttCell * nc = ftt_cell_neighbor (c, perpendicular[i][j]);
+
+	  if (nc && !FTT_CELL_IS_LEAF (nc))
+	    return TRUE;
+#else  /* FTT_3D */
+	  static guint perpendicular[FTT_NEIGHBORS][FTT_CELLS/2][2] =
+	  {{{4,2},{4,3},{5,2},{5,3}},
+	   {{4,2},{4,3},{5,2},{5,3}},
+	   {{4,1},{4,0},{5,1},{5,0}},
+	   {{4,1},{4,0},{5,1},{5,0}},
+	   {{2,1},{2,0},{3,1},{3,0}},
+	   {{2,1},{2,0},{3,1},{3,0}}};
+	  FttCell * nc0, * nc1;
+
+	  nc0 = ftt_cell_neighbor (c, perpendicular[i][j][0]);
+	  if (nc0 && !FTT_CELL_IS_LEAF (nc0))
+	    return TRUE;
+	  nc1 = ftt_cell_neighbor (c, perpendicular[i][j][1]);
+	  if (nc1 && !FTT_CELL_IS_LEAF (nc1))
+	    return TRUE;
+#endif /* FTT_3D */
+	  if (!FTT_CELL_IS_LEAF (c)) {
+	    FttCellChildren child;
+	    guint j, k;
+
+	    k = ftt_cell_children_direction (c, FTT_OPPOSITE_DIRECTION (i), &child);
+	    for (j = 0; j < k; j++)
+	      if (child.c[j])
+		return TRUE;
+	  }
+	}
+      }	
+    }
+  }
+
+  return FALSE;
+}
+
+static void copy_cell (const FttCell * from,
+		       FttCell * to,
+		       FttCellCopyFunc copy,
+		       gpointer data)
+{
+  to->flags = from->flags;
+
+  if (!FTT_CELL_IS_DESTROYED (from)) {
+    if (copy)
+      (* copy) (from, to, data);
+    
+    if (!FTT_CELL_IS_LEAF (from)) {
+      FttOct * oct_from = from->children;
+      FttOct * oct_to;
+      guint n;
+      
+      oct_new (to, FALSE, NULL, NULL);
+      oct_to = to->children;
+      for (n = 0; n < FTT_CELLS; n++)
+	copy_cell (&(oct_from->cell[n]), &(oct_to->cell[n]), copy, data);
+    }
+  }
+}
+
+/**
+ * ftt_cell_copy:
+ * @root: the root of the cell tree to copy.
+ * @copy: a #FttCellCopyFunc or %NULL.
+ * @data: user data to pass to @copy.
+ *
+ * Returns: a new #FttCell root of the cell tree copy of @root. The
+ * attributes of the cells are copied using the user-defined @copy
+ * function.
+ */
+FttCell * ftt_cell_copy (const FttCell * root,
+			 FttCellCopyFunc copy,
+			 gpointer data)
+{
+  FttCell * root_copy;
+
+  g_return_val_if_fail (root != NULL, NULL);
+
+  root_copy = ftt_cell_new (NULL, NULL);
+  ftt_cell_neighbors (root, &FTT_ROOT_CELL (root_copy)->neighbors);
+  ftt_cell_pos (root, &FTT_ROOT_CELL (root_copy)->pos);
+  FTT_ROOT_CELL (root_copy)->level = ftt_cell_level (root);
+							   
+  copy_cell (root, root_copy, copy, data);
+
+  return root_copy;
+}
+
+#include "ftt_internal.c"
+
+/**
+ * ftt_face_traverse:
+ * @root: the root #FttCell of the tree to traverse.
+ * @c: only the faces orthogonal to this component will be traversed - one of
+ * %FTT_X, %FTT_Y, (%FTT_Z), %FTT_XYZ.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children and faces are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCellFace.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each face of the cells of the tree.
+ *
+ * If %FTT_TRAVERSE_BOUNDARY_FACES is not set in @flags, only
+ * "double-sided" faces are traversed i.e. the @neighbor field of the
+ * face is never %NULL.  
+ */
+void ftt_face_traverse (FttCell * root,
+			FttComponent c,
+			FttTraverseType order,
+			FttTraverseFlags flags,
+			gint max_depth,
+			FttFaceTraverseFunc func,
+			gpointer data)
+{
+  FttDirection d;
+  gpointer datum[6];
+  gboolean check = FALSE;
+  gboolean boundary_faces;
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (c >= FTT_X && c <= FTT_XYZ);
+  g_return_if_fail (func != NULL);
+
+  boundary_faces = ((flags & FTT_TRAVERSE_BOUNDARY_FACES) != 0);
+  datum[1] = &max_depth;
+  datum[2] = func;
+  datum[3] = data;
+  datum[4] = &check;
+  datum[5] = &boundary_faces;
+  if (c == FTT_XYZ) {
+    if (boundary_faces) {
+      check = TRUE;
+      ftt_cell_traverse (root, order, flags, max_depth, 
+			 (FttCellTraverseFunc) traverse_all_faces, 
+			 datum);
+    }
+    else {
+      ftt_cell_traverse (root, order, flags, max_depth, 
+			 (FttCellTraverseFunc) traverse_all_direct_faces, 
+			 datum);
+      check = TRUE;
+      datum[0] = &d;
+      for (d = 1; d < FTT_NEIGHBORS; d += 2)
+	ftt_cell_traverse_boundary (root, d, order, flags, max_depth, 
+				    (FttCellTraverseFunc) traverse_face, 
+				    datum);
+    }
+  }
+  else {
+    if (boundary_faces) {
+      check = TRUE;
+      datum[0] = &c;
+      ftt_cell_traverse (root, order, flags, max_depth, 
+			 (FttCellTraverseFunc) traverse_face_component,
+			 datum);
+    }
+    else {
+      d = 2*c;
+      datum[0] = &d;
+      ftt_cell_traverse (root, order, flags, max_depth, 
+			 (FttCellTraverseFunc) traverse_face_direction, datum);
+      d = 2*c + 1;
+      check = TRUE;
+      ftt_cell_traverse_boundary (root, d, order, flags, max_depth, 
+				  (FttCellTraverseFunc) traverse_face, datum);
+    }
+  }
+  ftt_cell_traverse (root, order, flags, max_depth, 
+		     (FttCellTraverseFunc) reset_flag, NULL);
+}
+
+static void traverse_face_boundary (FttCell * cell, gpointer * datum) 
+{
+  FttDirection * d = datum[0];
+  FttFaceTraverseFunc func = (FttFaceTraverseFunc) datum[1];
+  gpointer data = datum[2];
+  FttCellFace face;
+  
+  face.d = *d;
+  face.cell = cell;
+  face.neighbor = ftt_cell_neighbor (cell, face.d);
+  (* func) (&face, data);
+}
+
+/**
+ * ftt_face_traverse_boundary:
+ * @root: the root #FttCell of the tree to traverse.
+ * @d: the direction of the boundary to visit.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ * @func: the function to call for each visited #FttCellFace.
+ * @data: user data to pass to @func.
+ *
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each face of the cell tree forming the
+ * boundary of the domain in direction @d.  
+ */
+void ftt_face_traverse_boundary (FttCell * root,
+				 FttDirection d,
+				 FttTraverseType order,
+				 FttTraverseFlags flags,
+				 gint max_depth,
+				 FttFaceTraverseFunc func,
+				 gpointer data)
+{
+  gpointer datum[3];
+
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (d < FTT_NEIGHBORS);
+  g_return_if_fail (func != NULL);
+
+  datum[0] = &d;
+  datum[1] = func;
+  datum[2] = data;
+  ftt_cell_traverse_boundary (root, d, order, flags, max_depth, 
+			      (FttCellTraverseFunc) traverse_face_boundary, 
+			      datum);
+}
+
+/**
+ * ftt_cell_coarsen:
+ * @root: a #FttCell root of a cell tree to coarsen.
+ * @coarsen: a #FttCellCoarsenFunc.
+ * @coarsen_data: user data to pass to @coarsen.
+ * @cleanup: a #FttCellCleanupFunc to call before destroying a cell or %NULL.
+ * @cleanup_data: user data to pass to @cleanup.
+ *
+ * Coarsens the cell tree defined by @root according to @coarsen.
+ *
+ * Returns: %TRUE if @root has been coarsened (i.e. @root is now a
+ * leaf cell), %FALSE otherwise.
+ */
+gboolean ftt_cell_coarsen (FttCell * root,
+			   FttCellCoarsenFunc coarsen,
+			   gpointer coarsen_data,
+			   FttCellCleanupFunc cleanup,
+			   gpointer cleanup_data)
+{
+  guint i, n;
+  gboolean coarsenable = TRUE;
+  
+  g_return_val_if_fail (root != NULL, FALSE);
+  g_return_val_if_fail (coarsen != NULL, FALSE);
+
+  if (FTT_CELL_IS_LEAF (root))
+    return (* coarsen) (root, coarsen_data);
+
+  for (i = 0; i < FTT_CELLS; i++)
+    if (!FTT_CELL_IS_DESTROYED (&(root->children->cell[i])))
+      coarsenable &= ftt_cell_coarsen (&(root->children->cell[i]), 
+				       coarsen, coarsen_data, 
+				       cleanup, cleanup_data);
+  if (!coarsenable || !(* coarsen) (root, coarsen_data))
+    return FALSE;
+
+  {
+    FttDirection d;
+
+    for (d = 0; d < FTT_NEIGHBORS; d++) {
+      FttCellChildren child;
+
+      n = ftt_cell_children_direction (root, d, &child);
+      for (i = 0; i < n; i++) {
+	FttCell * neighbor;
+
+	if (child.c[i] && (neighbor = ftt_cell_neighbor (child.c[i], d)) &&
+	    !FTT_CELL_IS_LEAF (neighbor)) {
+	  FttCellChildren child1;
+	  guint j, k;
+	  gboolean empty = TRUE;
+
+	  k = ftt_cell_children_direction (neighbor, FTT_OPPOSITE_DIRECTION (d), &child1);
+	  for (j = 0; j < k && empty; j++)
+	    if (child1.c[j])
+	      empty = FALSE;
+	  if (!empty && !ftt_cell_coarsen (neighbor, coarsen, coarsen_data, 
+					   cleanup, cleanup_data))
+	    return FALSE;
+	}
+      }
+    }
+  }
+
+  if (cleanup)
+    for (i = 0; i < FTT_CELLS; i++)
+      if (!FTT_CELL_IS_DESTROYED (&(root->children->cell[i])))
+	(* cleanup) (&(root->children->cell[i]), cleanup_data);
+  g_free (root->children);
+  root->children = NULL;
+
+  return TRUE;
+}
+
+/**
+ * ftt_direction_from_name:
+ * @name: a direction name.
+ *
+ * Returns: the index of the direction @name or %FTT_NEIGHBORS if
+ * @name is not a valid direction name.  
+ */
+FttDirection ftt_direction_from_name (const gchar * name)
+{
+  FttDirection d = 0;
+
+  g_return_val_if_fail (name != NULL, FTT_NEIGHBORS);
+
+  while (d < FTT_NEIGHBORS && strcmp (name, ftt_direction_name[d]))
+    d++;
+  return d;
+}
+
+static void cell_traverse_add (FttCell * cell, GPtrArray * a)
+{
+  g_ptr_array_add (a, cell);
+}
+
+/**
+ * ftt_cell_traverse_new:
+ * @root: the root #FttCell of the tree to traverse.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @max_depth: the maximum depth of the traversal. Cells below this
+ * depth will not be traversed. If @max_depth is -1 all cells in the
+ * tree are visited.
+ *
+ * Returns: a new #FttCellTraverse.
+ */
+FttCellTraverse * ftt_cell_traverse_new (FttCell * root,
+					 FttTraverseType order,
+					 FttTraverseFlags flags,
+					 gint max_depth)
+{
+  FttCellTraverse * t;
+  GPtrArray * a;
+
+  g_return_val_if_fail (root != NULL, NULL);
+
+  a = g_ptr_array_new ();
+  ftt_cell_traverse (root, order, flags, max_depth,
+		     (FttCellTraverseFunc) cell_traverse_add, a);
+  g_ptr_array_add (a, NULL);
+  t = g_malloc (sizeof (FttCellTraverse));
+  t->current = t->cells = (FttCell **) a->pdata;
+  g_ptr_array_free (a, FALSE);
+  return t;
+}
+
+/**
+ * ftt_cell_traverse_rewind:
+ * @t: a #FttCellTraverse.
+ *
+ * Sets @t at the begining of the traversal.
+ */
+void ftt_cell_traverse_rewind (FttCellTraverse * t)
+{
+  g_return_if_fail (t != NULL);
+
+  t->current = t->cells;
+}
+
+/**
+ * ftt_cell_traverse_destroy:
+ * @t: a #FttCellTraverse.
+ *
+ * Frees all the memory associated with @t.
+ */
+void ftt_cell_traverse_destroy (FttCellTraverse * t)
+{
+  g_return_if_fail (t != NULL);
+
+  g_free (t->cells);
+  g_free (t);
+}
+
diff --git a/src/ftt.h b/src/ftt.h
new file mode 100644
index 0000000..4d2a359
--- /dev/null
+++ b/src/ftt.h
@@ -0,0 +1,876 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __FTT_H__
+#define __FTT_H__
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <gts.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "gfsconfig.h"
+
+#define FTT_MAINTAINER "s.popinet at niwa.co.nz"
+
+#if (FTT_2D || FTT_2D3)
+# define FTT_CELLS     4
+#else  /* FTT_3D */
+# define FTT_CELLS     8
+#endif /* FTT_3D */
+
+typedef struct _FttCell          FttCell;
+typedef struct _FttCellFace      FttCellFace;
+typedef struct _FttCellNeighbors FttCellNeighbors;
+typedef struct _FttCellChildren  FttCellChildren;
+
+typedef struct _FttVector        FttVector;
+
+struct _FttVector {
+  gdouble x, y, z;
+};
+
+#if FTT_2D
+# define ftt_vector_norm(v) (sqrt((v)->x*(v)->x + (v)->y*(v)->y))
+#else  /* 3D */
+# define ftt_vector_norm(v) (sqrt((v)->x*(v)->x + (v)->y*(v)->y + (v)->z*(v)->z))
+#endif /* 3D */
+
+typedef enum
+{
+  FTT_TRAVERSE_LEAFS          = 1 << 0,
+  FTT_TRAVERSE_NON_LEAFS      = 1 << 1,
+  FTT_TRAVERSE_LEVEL          = 1 << 2,
+  FTT_TRAVERSE_BOUNDARY_FACES = 1 << 3,
+  FTT_TRAVERSE_DESTROYED      = 1 << 4,
+  FTT_TRAVERSE_ALL            = FTT_TRAVERSE_LEAFS | FTT_TRAVERSE_NON_LEAFS
+} FttTraverseFlags;
+
+typedef enum
+{
+  FTT_PRE_ORDER,
+  FTT_POST_ORDER
+} FttTraverseType;
+
+typedef enum
+{
+  FTT_RIGHT = 0,
+  FTT_LEFT,
+  FTT_TOP,
+  FTT_BOTTOM,
+#if (!FTT_2D)
+  FTT_FRONT,
+  FTT_BACK,
+#endif /* FTT_3D || FTT_2D3 */
+  FTT_NEIGHBORS
+} FttDirection;
+
+#define FTT_NEIGHBORS_2D (FTT_BOTTOM + 1)
+
+#if FTT_2D3
+# define FTT_CELLS_DIRECTION(d) ((d) < FTT_NEIGHBORS_2D ? FTT_CELLS/2 : FTT_CELLS)
+#else  /* 2D && 3D */
+# define FTT_CELLS_DIRECTION(d) (FTT_CELLS/2)
+#endif /* 2D && 3D */
+
+GTS_C_VAR gchar * ftt_direction_name[FTT_NEIGHBORS]; /* defined in ftt.c */
+
+typedef enum
+{
+  FTT_X = 0,
+  FTT_Y,
+#if (!FTT_2D)
+  FTT_Z,
+#endif /* FTT_3D || FTT_2D3 */
+  FTT_DIMENSION,
+  FTT_XY,
+#if FTT_2D
+  FTT_XYZ = FTT_XY
+#else  /* FTT_3D || FTT_2D3 */
+  FTT_XYZ
+#endif /* FTT_3D || FTT_2D3 */
+} FttComponent;
+
+typedef enum {
+  FTT_FLAG_ID        = 7,
+  FTT_FLAG_DESTROYED = 1 << 3,
+  FTT_FLAG_LEAF      = 1 << 4,        /* used only for I/O operations */
+  FTT_FLAG_TRAVERSED = FTT_FLAG_LEAF, /* used for face traversal */
+  FTT_FLAG_USER      =      5         /* user flags start here */
+} FttCellFlags;
+
+typedef void      (* FttCellTraverseFunc)            (FttCell * cell,
+						      gpointer data);
+typedef void      (* FttCellInitFunc)                (FttCell * cell,
+						      gpointer data);
+
+struct _FttCellNeighbors {
+  /* right, left, top, bottom, front, back */
+  FttCell * c[FTT_NEIGHBORS];
+};
+
+struct _FttCellChildren {
+  FttCell * c[FTT_CELLS];
+};
+
+struct _FttCell {
+  /*< public >*/
+  guint flags;
+  gpointer data;
+
+  /*< private >*/
+  struct _FttOct * parent, * children;
+};
+
+struct _FttRootCell {
+  FttCell cell;
+
+  FttCellNeighbors neighbors;
+  FttVector pos;
+  guint level;
+#if FTT_2D3
+  gdouble dz;
+#endif
+  gpointer parent;
+};
+
+struct _FttOct {
+  guint level;
+  FttCell * parent;
+  FttCellNeighbors neighbors;
+  FttVector pos;
+#if FTT_2D3
+  gdouble dz;
+#endif
+
+  FttCell cell[FTT_CELLS];
+};
+
+struct _FttCellFace {
+  FttCell * cell, * neighbor;
+  FttDirection d;
+};
+
+#define  FTT_ROOT_CELL(c)         ((struct _FttRootCell *) c)
+#define  FTT_CELL_ID(c)           ((c)->flags & FTT_FLAG_ID)
+#define  FTT_CELL_IS_LEAF(c)      ((c)->children == NULL)
+#define  FTT_CELL_IS_ROOT(c)      ((c)->parent == NULL)
+#define  FTT_CELL_IS_DESTROYED(c) (((c)->flags & FTT_FLAG_DESTROYED) != 0)
+
+typedef enum {
+  FTT_BOUNDARY,
+  FTT_FINE_FINE,
+  FTT_FINE_COARSE
+} FttFaceType;
+
+#define  FTT_FACE_DIRECT(f)       ((f)->d % 2 == 0)
+#define  FTT_FACE_REVERSE(dst, src) \
+   ((dst)->cell = (src)->neighbor,\
+    (dst)->neighbor = (src)->cell,\
+    (dst)->d = FTT_OPPOSITE_DIRECTION((src)->d))
+
+GTS_C_VAR
+gint                 ftt_opposite_direction[FTT_NEIGHBORS];
+
+#define FTT_OPPOSITE_DIRECTION(d)     (ftt_opposite_direction[d])
+#define FTT_ORTHOGONAL_COMPONENT(c)   (((c) + 1) % FTT_DIMENSION)
+
+#ifdef G_DISABLE_ASSERT
+
+#define g_assert_not_implemented()
+
+#else /* !G_DISABLE_ASSERT */
+
+#ifdef __GNUC__
+
+#define g_assert_not_implemented()      G_STMT_START{		\
+     g_log (G_LOG_DOMAIN,					\
+	    G_LOG_LEVEL_ERROR,					\
+	    "file %s: line %d (%s): not implemented (yet)",	\
+	    __FILE__,						\
+	    __LINE__,						\
+	    __PRETTY_FUNCTION__);	}G_STMT_END
+
+#else /* !__GNUC__ */
+
+#define g_assert_not_implemented()	G_STMT_START{	\
+     g_log (G_LOG_DOMAIN,				\
+	    G_LOG_LEVEL_ERROR,				\
+	    "file %s: line %d: not implemented (yet)",	\
+	    __FILE__,					\
+	    __LINE__);		}G_STMT_END
+
+#endif /* __GNUC__ */
+
+#endif /* !G_DISABLE_ASSERT */
+
+FttCell *            ftt_cell_new                    (FttCellInitFunc init,
+						      gpointer data);
+#define              ftt_cell_level(c)  ((c)->parent ?\
+                                         (c)->parent->level + 1 :\
+                                         ((struct _FttRootCell *) c)->level)
+#define              ftt_cell_parent(c) ((c)->parent ?\
+                                         (c)->parent->parent : NULL)
+#ifdef FTT_2D3
+# define             ftt_cell_dz(c)     ((c)->parent ?\
+                                         (c)->parent->dz :\
+                                         ((struct _FttRootCell *) c)->dz)
+#else  /* 2D or 3D */
+# define             ftt_cell_dz(c)     (1.)
+#endif /* 2D or 3D */
+
+/**
+ * ftt_level_size:
+ * @level: a guint.
+ *
+ * Returns: the size of a cell of level @level.
+ */
+static inline
+gdouble ftt_level_size (guint level)
+{
+  gdouble size = 1.;
+
+  while (level) {
+    size /= 2.;
+    level--;
+  }
+
+  return size;
+}
+
+/**
+ * ftt_cell_size:
+ * @cell: a #FttCell.
+ *
+ * Returns: the size of @cell.
+ */
+static inline
+gdouble ftt_cell_size (const FttCell * cell)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  return ftt_level_size (ftt_cell_level (cell));
+}
+
+/**
+ * ftt_cell_volume:
+ * @cell: a #FttCell.
+ *
+ * Returns: the volume (area in 2D) of @cell.
+ */
+static inline
+gdouble ftt_cell_volume (const FttCell * cell)
+{
+  gdouble size;
+
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  size = ftt_level_size (ftt_cell_level (cell));
+#if (FTT_2D || FTT_2D3)
+  return size*size;
+#else  /* FTT_3D */
+  return size*size*size;
+#endif /* FTT_3D */
+}
+
+/**
+ * ftt_cell_children:
+ * @cell: a #FttCell.
+ * @children: a #FttCellChildren.
+ *
+ * Fills @children with the children of @cell.
+ * 
+ * This function fails if @cell is a leaf.
+ */
+static inline
+void ftt_cell_children (const FttCell * cell,
+			FttCellChildren * children)
+{
+  struct _FttOct * oct;
+  guint i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (cell));
+  g_return_if_fail (children != NULL);
+
+  oct = cell->children;
+  for (i = 0; i < FTT_CELLS; i++)
+    children->c[i] = FTT_CELL_IS_DESTROYED (&(oct->cell[i])) ? 
+      NULL : &(oct->cell[i]);
+}
+
+/**
+ * ftt_cell_children_direction:
+ * @cell: a #FttCell.
+ * @d: a direction.
+ * @children: a #FttCellChildren.
+ *
+ * Fills @children with the children (2 in 2D, 4 in 3D, 2 or 4 in 2D3)
+ * of @cell in direction @d.
+ * 
+ * This function fails if @cell is a leaf.
+ *
+ * Returns: the number of children in direction @d.
+ */
+static inline
+guint ftt_cell_children_direction (const FttCell * cell,
+				   FttDirection d,
+				   FttCellChildren * children)
+{
+  struct _FttOct * oct;
+  guint i;
+#if (FTT_2D || FTT_2D3)
+  static gint index[FTT_NEIGHBORS_2D][FTT_CELLS/2] =
+  {{1, 3},
+   {0, 2},
+   {0, 1},
+   {2, 3}};
+#else  /* FTT_3D */
+  static gint index[FTT_NEIGHBORS][FTT_CELLS/2] =
+  {{1, 3, 5, 7},
+   {0, 2, 4, 6},
+   {0, 1, 4, 5},
+   {2, 3, 6, 7},
+   {0, 1, 2, 3},
+   {4, 5, 6, 7}};
+#endif /* FTT_3D */
+
+  g_return_val_if_fail (cell != NULL, 0);
+  g_return_val_if_fail (!FTT_CELL_IS_LEAF (cell), 0);
+  g_return_val_if_fail (d < FTT_NEIGHBORS, 0);
+  g_return_val_if_fail (children != NULL, 0);
+
+  oct = cell->children;
+
+#if FTT_2D3
+  if (d >= FTT_NEIGHBORS_2D) {
+    for (i = 0; i < FTT_CELLS; i++)
+      children->c[i] = FTT_CELL_IS_DESTROYED (&(oct->cell[i])) ? NULL : &(oct->cell[i]);
+    return FTT_CELLS;
+  }
+#endif /* 2D3 */
+
+  for (i = 0; i < FTT_CELLS/2; i++)
+    children->c[i] = FTT_CELL_IS_DESTROYED (&(oct->cell[index[d][i]])) ? 
+      NULL : &(oct->cell[index[d][i]]);
+  return FTT_CELLS/2;
+}
+
+/**
+ * ftt_cell_child_corner:
+ * @cell: a #FttCell.
+ * @d: a set of perpendicular directions.
+ *
+ * This function fails if @cell is a leaf.  
+ *
+ * Returns: the children of @cell in the corner defined by directions @d.
+ */
+static inline
+FttCell * ftt_cell_child_corner (const FttCell * cell,
+				 FttDirection d[FTT_DIMENSION])
+{
+#if (FTT_2D || FTT_2D3)
+  static gint index[FTT_NEIGHBORS_2D][FTT_NEIGHBORS_2D] = {
+    {-1,-1,1,3},
+    {-1,-1,0,2},
+    {1,0,-1,-1},
+    {3,2,-1,-1}
+  };
+  gint i;
+
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (!FTT_CELL_IS_LEAF (cell), NULL);
+
+  g_return_val_if_fail (d[0] < FTT_NEIGHBORS, NULL);
+  g_return_val_if_fail (d[1] < FTT_NEIGHBORS, NULL);
+
+#  if FTT_2D3
+  if (d[0] >= FTT_NEIGHBORS_2D)
+    i = index[d[1]][d[2]];
+  else if (d[1] >= FTT_NEIGHBORS_2D)
+    i = index[d[0]][d[2]];
+  else
+#  endif
+    i = index[d[0]][d[1]];
+#else  /* FTT_3D */
+  static gint index[FTT_NEIGHBORS][FTT_NEIGHBORS][FTT_NEIGHBORS] = {
+    {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},
+     {-1,-1,-1,-1,1,5},{-1,-1,-1,-1,3,7},
+     {-1,-1,1,3,-1,-1},{-1,-1,5,7,-1,-1}},
+    {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},
+     {-1,-1,-1,-1,0,4},{-1,-1,-1,-1,2,6},
+     {-1,-1,0,2,-1,-1},{-1,-1,4,6,-1,-1}},
+    {{-1,-1,-1,-1,1,5},{-1,-1,-1,-1,0,4},
+     {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},
+     {1,0,-1,-1,-1,-1},{5,4,-1,-1,-1,-1}},
+    {{-1,-1,-1,-1,3,7},{-1,-1,-1,-1,2,6},
+     {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},
+     {3,2,-1,-1,-1,-1},{7,6,-1,-1,-1,-1}},
+    {{-1,-1,1,3,-1,-1},{-1,-1,0,2,-1,-1},
+     {1,0,-1,-1,-1,-1},{3,2,-1,-1,-1,-1},
+     {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1}},
+    {{-1,-1,5,7,-1,-1},{-1,-1,4,6,-1,-1},
+     {5,4,-1,-1,-1,-1},{7,6,-1,-1,-1,-1},
+     {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1}},
+  };
+  gint i;
+
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (!FTT_CELL_IS_LEAF (cell), NULL);
+  g_return_val_if_fail (d[0] < FTT_NEIGHBORS, NULL);
+  g_return_val_if_fail (d[1] < FTT_NEIGHBORS, NULL);
+  g_return_val_if_fail (d[2] < FTT_NEIGHBORS, NULL);
+
+  i = index[d[0]][d[1]][d[2]];
+#endif /* FTT_3D */
+
+  g_return_val_if_fail (i >= 0, NULL);
+
+  return FTT_CELL_IS_DESTROYED (&(cell->children->cell[i])) ? NULL:
+    &(cell->children->cell[i]);
+}
+
+/**
+ * ftt_cell_neighbors_not_cached:
+ * @cell: a #FttCell.
+ * @neighbors: a #FttCellNeighbors.
+ *
+ * Fills @neighbors with the neighbors of @cell (does not use saved
+ * values even if available).  
+ */
+static inline
+void ftt_cell_neighbors_not_cached (const FttCell * cell,
+				    FttCellNeighbors * neighbors)
+{
+  static gint neighbor_index[FTT_NEIGHBORS][FTT_CELLS]
+#if FTT_2D
+    = {{1,-1,3,-3},
+       {-2,0,-4,2},
+       {-3,-4,0,1},
+       {2,3,-1,-2}};
+#elif FTT_2D3
+    = {{1,-1,3,-3},
+       {-2,0,-4,2},
+       {-3,-4,0,1},
+       {2,3,-1,-2},
+       {-1,-2,-3,-4},
+       {-1,-2,-3,-4}};
+#else  /* FTT_3D */
+    = {{1,-1,3,-3,5,-5,7,-7},
+       {-2,0,-4,2,-6,4,-8,6},
+       {-3,-4,0,1,-7,-8,4,5},
+       {2,3,-1,-2,6,7,-5,-6},
+       {-5,-6,-7,-8,0,1,2,3},
+       {4,5,6,7,-1,-2,-3,-4}};
+#endif /* FTT_3D */
+  guint n, d;
+  struct _FttOct * parent;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (neighbors != NULL);
+
+  if (FTT_CELL_IS_ROOT (cell)) {
+    memcpy (neighbors, &((struct _FttRootCell *) cell)->neighbors,
+	    sizeof (FttCellNeighbors));
+    return;
+  }
+
+  parent = cell->parent;
+  n = FTT_CELL_ID (cell);
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    gint nn = neighbor_index[d][n];
+    FttCell * c;
+
+    if (nn >= 0) /* neighbor belongs to same Oct */
+      c = &(parent->cell[nn]);
+    else {       /* neighbor belongs to neighboring Cell or Oct */
+      c = parent->neighbors.c[d];
+      if (c != NULL && c->children != NULL)
+	c = &(c->children->cell[- nn - 1]);
+    }
+    if (c == NULL || FTT_CELL_IS_DESTROYED (c))
+      neighbors->c[d] = NULL;
+    else
+      neighbors->c[d] = c;
+  }
+}
+
+/**
+ * ftt_cell_neighbor_not_cached:
+ * @cell: a #FttCell.
+ * @d: a direction.
+ *
+ * Returns: the neighbor of @cell in direction @d or %NULL if @cell
+ * has no neighbor in this direction (does not use saved values even
+ * if available).  
+ */
+static inline
+FttCell * ftt_cell_neighbor_not_cached (const FttCell * cell,
+					FttDirection d)
+{
+  static gint neighbor_index[FTT_NEIGHBORS][FTT_CELLS]
+#if FTT_2D
+    = {{1,-1,3,-3},
+       {-2,0,-4,2},
+       {-3,-4,0,1},
+       {2,3,-1,-2}};
+#elif FTT_2D3
+    = {{1,-1,3,-3},
+       {-2,0,-4,2},
+       {-3,-4,0,1},
+       {2,3,-1,-2},
+       {-1,-2,-3,-4},
+       {-1,-2,-3,-4}};
+#else  /* FTT_3D */
+    = {{1,-1,3,-3,5,-5,7,-7},
+       {-2,0,-4,2,-6,4,-8,6},
+       {-3,-4,0,1,-7,-8,4,5},
+       {2,3,-1,-2,6,7,-5,-6},
+       {-5,-6,-7,-8,0,1,2,3},
+       {4,5,6,7,-1,-2,-3,-4}};
+#endif /* FTT_3D */
+  gint n;
+  FttCell * c;
+
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (d < FTT_NEIGHBORS, NULL);
+
+  if (FTT_CELL_IS_ROOT (cell))
+    return ((struct _FttRootCell *) cell)->neighbors.c[d];
+
+  n = neighbor_index[d][FTT_CELL_ID (cell)];
+  if (n >= 0) /* neighbor belongs to same Oct */
+    c = &(cell->parent->cell[n]);
+  else {      /* neighbor belongs to neighboring Cell or Oct */
+    c = cell->parent->neighbors.c[d];
+    if (c != NULL && c->children != NULL)
+      c = &(c->children->cell[- n - 1]);
+  }
+  if (c == NULL || FTT_CELL_IS_DESTROYED (c))
+    return NULL;
+  else
+    return c;
+}
+
+/**
+ * ftt_cell_neighbors:
+ * @cell: a #FttCell.
+ * @neighbors: a #FttCellNeighbors.
+ *
+ * Fills @neighbors with the neighbors of @cell.
+ */
+static inline
+void ftt_cell_neighbors (const FttCell * cell,
+			 FttCellNeighbors * neighbors)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (neighbors != NULL);
+
+  if (!FTT_CELL_IS_LEAF (cell) && neighbors != &cell->children->neighbors) {
+    memcpy (neighbors, &cell->children->neighbors, sizeof (FttCellNeighbors));
+    return;
+  }
+
+  ftt_cell_neighbors_not_cached (cell, neighbors);
+}
+
+/**
+ * ftt_cell_neighbor:
+ * @cell: a #FttCell.
+ * @d: a direction.
+ *
+ * Returns: the neighbor of @cell in direction @d or %NULL if @cell
+ * has no neighbor in this direction.  
+ */
+static inline
+FttCell * ftt_cell_neighbor (const FttCell * cell,
+			     FttDirection d)
+{
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (d < FTT_NEIGHBORS, NULL);
+
+  if (!FTT_CELL_IS_LEAF (cell))
+    return cell->children->neighbors.c[d];
+
+  return ftt_cell_neighbor_not_cached (cell, d);
+}
+
+/**
+ * ftt_cell_face:
+ * @cell: a #FttCell.
+ * @d: a direction.
+ *
+ * Returns: the face of @cell in direction @d.
+ */
+static inline
+FttCellFace ftt_cell_face (FttCell * cell,
+			   FttDirection d)
+{
+  FttCellFace f;
+
+  g_return_val_if_fail (cell != NULL, f);
+
+  f.cell = cell;
+  f.neighbor = ftt_cell_neighbor (cell, d);
+  f.d = d;
+
+  return f;
+}
+
+/**
+ * ftt_face_type:
+ * @face: a #FttCellFace.
+ *
+ * Returns: the type of @face.
+ */
+static inline
+FttFaceType ftt_face_type (const FttCellFace * face)
+{
+  g_return_val_if_fail (face != NULL, 0);
+
+  if (face->neighbor == NULL)
+    return FTT_BOUNDARY;
+  if (ftt_cell_level (face->cell) > ftt_cell_level (face->neighbor))
+    return FTT_FINE_COARSE;
+  g_assert (ftt_cell_level (face->cell) == ftt_cell_level (face->neighbor));
+  return FTT_FINE_FINE;
+}
+
+/**
+ * ftt_cell_neighbor_is_brother:
+ * @cell: a #FttCell.
+ * @d: a #FttDirection.
+ *
+ * Returns: %TRUE if a (potential) neighbor of @cell in direction @d
+ * and @cell would have the same parent, %FALSE otherwise.
+ */
+static inline
+gboolean ftt_cell_neighbor_is_brother (FttCell * cell, 
+				       FttDirection d)
+{
+  static gboolean b[FTT_CELLS][FTT_NEIGHBORS] = {
+#if FTT_2D
+    {1,0,0,1}, {0,1,0,1}, {1,0,1,0}, {0,1,1,0}
+#elif FTT_2D3
+    {1,0,0,1,0,0}, {0,1,0,1,0,0}, {1,0,1,0,0,0}, {0,1,1,0,0,0}
+#else  /* 3D */
+    {1,0,0,1,0,1}, {0,1,0,1,0,1}, {1,0,1,0,0,1}, {0,1,1,0,0,1},
+    {1,0,0,1,1,0}, {0,1,0,1,1,0}, {1,0,1,0,1,0}, {0,1,1,0,1,0}
+#endif /* 3D */
+  };
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+  
+  if (FTT_CELL_IS_ROOT (cell))
+    return FALSE;
+  return b[FTT_CELL_ID (cell)][d];
+}
+
+guint                ftt_cell_depth                  (const FttCell * root);
+void                 ftt_cell_set_neighbor           (FttCell * root,
+						      FttCell * neighbor,
+						      FttDirection d,
+						      FttCellInitFunc init,
+						      gpointer init_data);
+void                 ftt_cell_set_neighbor_match     (FttCell * root,
+						      FttCell * neighbor,
+						      FttDirection d,
+						      FttCellInitFunc init,
+						      gpointer init_data);
+void                 ftt_cell_relative_pos           (const FttCell * cell,
+						      FttVector * pos);
+void                 ftt_cell_pos                    (const FttCell * cell,
+						      FttVector * pos);
+void                 ftt_corner_relative_pos         (const FttCell * cell,
+						      FttDirection d[FTT_DIMENSION],
+						      FttVector * pos);
+void                 ftt_corner_pos                  (const FttCell * cell,
+						      FttDirection d[FTT_DIMENSION],
+						      FttVector * pos);
+void                 ftt_face_pos                    (const FttCellFace * face,
+						      FttVector * pos);
+void                 ftt_cell_set_pos                (FttCell * root,
+						      const FttVector * pos);
+void                 ftt_cell_set_level              (FttCell * root,
+						      guint level);
+void                 ftt_cell_draw                   (const FttCell * cell,
+						      FILE * fp);
+void                 ftt_face_draw                   (const FttCellFace * face,
+						      FILE * fp);
+gboolean             ftt_cell_check                  (const FttCell * cell);
+typedef gboolean  (* FttCellRefineFunc)              (FttCell * cell,
+						      gpointer data);
+void                 ftt_cell_refine                 (FttCell * root,
+						      FttCellRefineFunc refine,
+						      gpointer refine_data,
+						      FttCellInitFunc init,
+						      gpointer init_data);
+void                 ftt_cell_refine_single          (FttCell * cell,
+						      FttCellInitFunc init,
+						      gpointer init_data);
+gboolean             ftt_refine_corner               (const FttCell * cell);
+void                 ftt_cell_traverse               (FttCell * root,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttCellTraverseFunc func,
+						      gpointer data);
+void                 ftt_cell_traverse_condition     (FttCell * root,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttCellTraverseFunc func,
+						      gpointer data,
+						      gboolean (* condition) (FttCell *, 
+									      gpointer),
+						      gpointer cdata);
+void                 ftt_cell_traverse_box           (FttCell * root,
+						      GtsBBox * box,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttCellTraverseFunc func,
+						      gpointer data);
+void                 ftt_cell_traverse_boundary      (FttCell * root,
+						      FttDirection d,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttCellTraverseFunc func,
+						      gpointer data);
+typedef void      (* FttFaceTraverseFunc)            (FttCellFace * face, 
+						      gpointer data);
+void                 ftt_face_traverse               (FttCell * root,
+						      FttComponent c,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttFaceTraverseFunc func,
+						      gpointer data);
+void                 ftt_face_traverse_boundary      (FttCell * root,
+						      FttDirection d,
+						      FttTraverseType order,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      FttFaceTraverseFunc func,
+						      gpointer data);
+FttCell *            ftt_cell_locate                 (FttCell * root,
+						      FttVector target,
+						      gint max_depth);
+gdouble              ftt_cell_point_distance2_min    (FttCell * cell, 
+						      GtsPoint * p);
+void                 ftt_cell_point_distance2_internal (FttCell * root,
+							GtsPoint * p,
+							gdouble d,
+							gdouble (* distance2) (FttCell *, 
+									       GtsPoint *, 
+									       gpointer),
+							gpointer data,
+							FttCell ** closest,
+							gdouble * dmin);
+gdouble              ftt_cell_point_distance2        (FttCell * root,
+						      GtsPoint * p,
+						      gdouble (* distance2) (FttCell *, 
+									     GtsPoint *, 
+									     gpointer),
+						      gpointer data,
+						      FttCell ** closest);
+void                 ftt_cell_bbox                   (const FttCell * cell, 
+						      GtsBBox * bb);
+typedef void      (* FttCellCopyFunc)                (const FttCell * from,
+						      FttCell * to,
+						      gpointer data);
+FttCell *            ftt_cell_copy                   (const FttCell * root,
+						      FttCellCopyFunc copy,
+						      gpointer data);
+typedef void      (* FttCellWriteFunc)               (const FttCell * cell,
+						      FILE * fp,
+						      gpointer data);
+void                 ftt_cell_write                  (const FttCell * root,
+						      gint max_depth,
+						      FILE * fp,
+						      FttCellWriteFunc write,
+						      gpointer data);
+void                 ftt_cell_write_binary           (const FttCell * root,
+						      gint max_depth,
+						      FILE * fp,
+						      FttCellWriteFunc write,
+						      gpointer data);
+typedef void      (* FttCellReadFunc)                (FttCell * cell,
+						      GtsFile * fp,
+						      gpointer data);
+FttCell *            ftt_cell_read                   (GtsFile * fp,
+						      FttCellReadFunc read,
+						      gpointer data);
+FttCell *            ftt_cell_read_binary            (GtsFile * fp,
+						      FttCellReadFunc read,
+						      gpointer data);
+typedef void      (* FttCellCleanupFunc)             (FttCell * cell,
+						      gpointer data);
+void                 ftt_cell_destroy           (FttCell * cell,
+						 FttCellCleanupFunc cleanup,
+						 gpointer data);
+void                 ftt_cell_destroy_root      (FttCell * root,
+						 FttCellChildren * children,
+						 FttCellCleanupFunc cleanup,
+						 gpointer data);
+void                 ftt_cell_flatten           (FttCell * root, 
+						 FttDirection d, 
+						 FttCellCleanupFunc cleanup,
+						 gpointer data);
+typedef gboolean  (* FttCellCoarsenFunc)        (FttCell * cell,
+						 gpointer data);
+gboolean             ftt_cell_coarsen           (FttCell * root,
+						 FttCellCoarsenFunc coarsen,
+						 gpointer coarsen_data,
+						 FttCellCleanupFunc cleanup,
+						 gpointer cleanup_data);
+FttDirection         ftt_direction_from_name    (const gchar * name);
+
+struct _FttCellTraverse {
+  FttCell ** cells;
+  FttCell ** current;
+};
+
+typedef struct _FttCellTraverse FttCellTraverse;
+
+FttCellTraverse *    ftt_cell_traverse_new      (FttCell * root,
+						 FttTraverseType order,
+						 FttTraverseFlags flags,
+						 gint max_depth);
+void                 ftt_cell_traverse_rewind   (FttCellTraverse * t);
+void                 ftt_cell_traverse_destroy  (FttCellTraverse * t);
+
+static inline
+FttCell * ftt_cell_traverse_next (FttCellTraverse * t)
+{
+  g_return_val_if_fail (t != NULL, NULL);
+
+  return *(t->current++);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __FTT_H__ */
diff --git a/src/ftt_internal.c b/src/ftt_internal.c
new file mode 100644
index 0000000..6cfe140
--- /dev/null
+++ b/src/ftt_internal.c
@@ -0,0 +1,82 @@
+static void traverse_face (FttCell * cell, gpointer * datum)
+{
+  FttDirection * d = datum[0];
+  gint max_depth = *((gint *) datum[1]);
+  FttFaceTraverseFunc func = (FttFaceTraverseFunc) datum[2];
+  gpointer data = datum[3];
+  gboolean check = *((gboolean *) datum[4]);
+  gboolean boundary_faces = *((gboolean *) datum[5]);  
+  FttCellFace face;
+  
+  face.d = *d;
+  face.cell = cell;
+  face.neighbor = ftt_cell_neighbor (cell, face.d);
+  if (face.neighbor) {
+    if (!check || (face.neighbor->flags & FTT_FLAG_TRAVERSED) == 0) {
+      if (FTT_CELL_IS_LEAF (cell) && 
+	  !FTT_CELL_IS_LEAF (face.neighbor) && 
+	  (max_depth < 0 || ftt_cell_level (face.neighbor) < max_depth)) {
+	/* coarse -> fine */
+	FttCellChildren children;
+	guint i, n;
+	
+	face.d = FTT_OPPOSITE_DIRECTION (face.d);
+	n = ftt_cell_children_direction (face.neighbor, face.d, &children);
+	face.neighbor = face.cell;
+	for (i = 0; i < n; i++)
+	  if ((face.cell = children.c[i]) && 
+	      (!check || (face.cell->flags & FTT_FLAG_TRAVERSED) == 0))
+	    (* func) (&face, data);
+      }
+      else
+	(* func) (&face, data);
+    }
+  }
+  else if (boundary_faces)
+    (* func) (&face, data);
+}
+
+static void traverse_all_faces (FttCell * cell, gpointer * datum)
+{
+  FttDirection d;
+
+  datum[0] = &d;
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    traverse_face (cell, datum);
+  cell->flags |= FTT_FLAG_TRAVERSED;
+}
+
+static void traverse_all_direct_faces (FttCell * cell, gpointer * datum)
+{
+  FttDirection d;
+
+  datum[0] = &d;
+  for (d = 0; d < FTT_NEIGHBORS; d += 2)
+    traverse_face (cell, datum);
+  cell->flags |= FTT_FLAG_TRAVERSED;
+}
+
+static void traverse_face_direction (FttCell * cell, gpointer * datum)
+{
+  traverse_face (cell, datum);
+  cell->flags |= FTT_FLAG_TRAVERSED;
+}
+
+static void traverse_face_component (FttCell * cell, gpointer * datum)
+{
+  FttComponent * c = datum[0];
+  FttDirection d;
+
+  datum[0] = &d;
+  d = 2*(*c);
+  traverse_face (cell, datum);
+  d++;
+  traverse_face (cell, datum);
+  cell->flags |= FTT_FLAG_TRAVERSED;
+  datum[0] = c;
+}
+
+static void reset_flag (FttCell * cell)
+{
+  cell->flags &= ~FTT_FLAG_TRAVERSED;
+}
diff --git a/src/function.h b/src/function.h
new file mode 100644
index 0000000..e9b8466
--- /dev/null
+++ b/src/function.h
@@ -0,0 +1,67 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __FUNCTION_H__
+#define __FUNCTION_H__
+
+static double Dirichlet = 1.;
+static double Neumann = 0.;
+static GfsSimulation * _sim = NULL;
+static FttCell * _cell = NULL;
+
+static double dd (const gchar * name, FttComponent c) {
+  GfsVariable * v = gfs_variable_from_name (GFS_DOMAIN (_sim)->variables, name);
+  if (v == NULL)
+    return 0.;
+  g_return_val_if_fail (_cell != NULL, 0.);
+  return gfs_dimensional_value (v, gfs_center_gradient (_cell, c, v->i)/
+				(_sim->physical_params.L*ftt_cell_size (_cell)));
+}
+
+static double dx (const gchar * name) { return dd (name, FTT_X); }
+static double dy (const gchar * name) { return dd (name, FTT_Y); }
+#if !FTT_2D
+static double dz (const gchar * name) { return dd (name, FTT_Z); }
+#endif /* 3D */
+
+static double area (const gchar * name)
+{
+  GfsVariable * v = gfs_variable_from_name (GFS_DOMAIN (_sim)->variables, name);
+  if (v == NULL || !GFS_IS_VARIABLE_TRACER_VOF (v))
+    return 0.;
+  g_return_val_if_fail (_cell != NULL, 0.);
+  GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+  FttVector m, p;
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m.x)[c] = GFS_VALUE (_cell, t->m[c]);
+  return gfs_plane_area_center (&m, GFS_VALUE (_cell, t->alpha), &p)/
+    (_sim->physical_params.L*ftt_cell_size (_cell));
+}
+
+static double correctness (const gchar * name)
+{
+  GfsVariable * v = gfs_variable_from_name (GFS_DOMAIN (_sim)->variables, name);
+  if (v == NULL || !GFS_IS_VARIABLE_TRACER_VOF (v))
+    return 0.;
+  g_return_val_if_fail (_cell != NULL, 0.);
+  return gfs_vof_correctness (_cell, GFS_VARIABLE_TRACER_VOF (v));
+}
+
+#endif /* __FUNCTION_H__ */
diff --git a/src/gerris.c b/src/gerris.c
new file mode 100644
index 0000000..c03c1dd
--- /dev/null
+++ b/src/gerris.c
@@ -0,0 +1,362 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "init.h"
+#include "simulation.h"
+#include "refine.h"
+#include "output.h"
+#include "adaptive.h"
+#include "solid.h"
+#include "version.h"
+
+static void set_box_pid (GfsBox * box, gint * pid)
+{
+  box->pid = *pid;
+}
+
+static void setup_binary_IO (GfsDomain * domain)
+{
+  /* make sure that all the variables are sent */
+  g_slist_free (domain->variables_io);
+  domain->variables_io = NULL;
+  GSList * i = domain->variables;
+  while (i) {
+    if (GFS_VARIABLE1 (i->data)->name)
+      domain->variables_io = g_slist_append (domain->variables_io, i->data);
+    i = i->next;
+  }
+  domain->binary = TRUE;	
+}
+
+int main (int argc, char * argv[])
+{
+  GfsSimulation * simulation;
+  GfsDomain * domain;
+  FILE * fptr;
+  GtsFile * fp;
+  int c = 0;
+  guint split = 0;
+  guint npart = 0;
+  gboolean profile = FALSE, macros = FALSE, one_box_per_pe = TRUE, bubble = FALSE, verbose = FALSE;
+  gchar * m4_options = g_strdup ("-P");
+  GPtrArray * events = g_ptr_array_new ();
+  gint maxlevel = -2;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"split", required_argument, NULL, 's'},
+      {"pid", no_argument, NULL, 'i'},
+      {"partition", required_argument, NULL, 'p'},
+      {"profile", no_argument, NULL, 'P'},
+      {"define", required_argument, NULL, 'D'},
+      {"macros", no_argument, NULL, 'm'},
+      {"data", no_argument, NULL, 'd'},
+      {"event", required_argument, NULL, 'e'},
+      {"bubble", required_argument, NULL, 'b'},
+      {"verbose", no_argument, NULL, 'v'},
+      {"help", no_argument, NULL, 'h'},
+      {"version", no_argument, NULL, 'V'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "hVs:ip:PD:mde:b:v",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "hVs:ip:PD:mde:b:v"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'P': /* profile */
+      profile = TRUE;
+      break;
+    case 'p': /* partition */
+      npart = atoi (optarg);
+      break;
+    case 'b': /* "bubble" partition */
+      npart = atoi (optarg);
+      bubble = TRUE;
+      break;
+    case 's': /* split */
+      split = atoi (optarg);
+      break;
+    case 'i': /* pid */
+      one_box_per_pe = FALSE;
+      break;
+    case 'D': { /* define */
+      gchar * tmp = g_strjoin (" ", m4_options, "-D", optarg, NULL);
+      g_free (m4_options);
+      m4_options = tmp;
+      /* fall through */
+    }
+    case 'm': /* macros */
+#ifndef HAVE_M4
+      gfs_error (0, "gerris: macros are not supported on this system\n");
+      return 1;
+#endif /* not HAVE_M4 */
+      macros = TRUE;
+      break;
+    case 'd': /* data */
+      maxlevel = -1;
+      break;
+    case 'e': /* event */
+      g_ptr_array_add (events, g_strdup (optarg));
+      break;
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      gfs_error (0,
+             "Usage: gerris [OPTION] FILE\n"
+	     "The Gerris flow solver simulation engine.\n"
+	     "\n"
+	     "  -s N   --split=N     splits the domain N times and returns\n"
+             "                       the corresponding simulation\n"
+	     "  -i     --pid         keep box pids when splitting\n"
+             "  -p N   --partition=N partition the domain in 2^N subdomains and returns\n" 
+             "                       the corresponding simulation\n"
+             "  -b N   --bubble=N    partition the domain in N subdomains and returns\n" 
+             "                       the corresponding simulation\n"
+	     "  -d     --data        when splitting or partitioning, output all data\n"
+	     "  -P     --profile     profiles calls to boundary conditions\n"
+#ifdef HAVE_M4
+	     "  -m     --macros      Turn macros support on\n"
+	     "  -DNAME               Defines NAME as a macro expanding to VALUE\n"
+	     "  -DNAME=VALUE         (macro support is implicitly turned on)\n"
+	     "         --define=NAME\n"
+             "         --define=NAME=VALUE\n"
+#endif /* HAVE_M4 */
+	     "  -eEV   --event=EV    Evaluates GfsEvent EV and returns the simulation\n"
+	     "  -v     --verbose     Display more messages\n"
+	     "  -h     --help        display this help and exit\n"
+	     "  -V     --version     output version information and exit\n"
+	     "\n"
+	     "Reports bugs to %s\n",
+	     FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case 'V': /* version */
+      gfs_error (0,
+	       "gerris: using %dD libgfs version %s (%s)\n"
+	       "  compiled with flags: %s\n"
+	       "  MPI:          %s\n"
+	       "  pkg-config:   %s\n"
+	       "  m4 and gawk:  %s\n"
+	       "Copyright (C) 2001-2009 NIWA.\n"
+	       "This is free software; see the source for copying conditions.  There is NO\n"
+	       "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+	       FTT_DIMENSION,
+	       GFS_VERSION,
+	       GFS_BUILD_VERSION,
+	       GFS_COMPILATION_FLAGS,
+#ifdef HAVE_MPI
+	       "yes",
+#else
+	       "no",
+#endif
+#ifdef HAVE_PKG_CONFIG
+	       "yes",
+#else
+	       "no",
+#endif
+#ifdef HAVE_M4
+	       "yes"
+#else
+	       "no"
+#endif
+	       );
+      return 0; /* succes */
+      break;
+    case '?': /* wrong options */
+      gfs_error (0, "Try `gerris --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  if (optind >= argc) { /* missing FILE */
+    gfs_error (0, 
+	     "gerris: missing FILE\n"
+	     "Try `gerris --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+  if (macros) {
+    const gchar awk[] = "gawk -f " GFS_MODULES_DIR "/m4.awk ";
+    gchar * command;
+    
+    if (!strcmp (argv[optind], "-"))
+      command = g_strjoin (NULL, awk, "| m4 ", m4_options, NULL);
+    else
+      command = g_strjoin (NULL, awk, argv[optind], " | m4 ", m4_options, NULL);
+    fptr = popen (command, "r");
+    g_free (command);
+  }
+  else { /* no macros */
+    if (!strcmp (argv[optind], "-"))
+      fptr = stdin;
+    else
+      fptr = fopen (argv[optind], "r");
+  }
+  g_free (m4_options);
+
+  if (fptr == NULL) {
+    gfs_error (-1, "gerris: unable to open file `%s'\n", argv[optind]);
+    return 1;
+  }
+
+  fp = gts_file_new (fptr);
+  if (!(simulation = gfs_simulation_read (fp))) {
+    gfs_error (-1, 
+	     "gerris: file `%s' is not a valid simulation file\n"
+	     "%s:%d:%d: %s\n",
+	     argv[optind], argv[optind],
+	     fp->line, fp->pos, fp->error);
+    return 1;
+  }
+  gts_file_destroy (fp);
+
+  if (macros)
+    pclose (fptr);
+  else
+    if (fptr != stdin)
+      fclose (fptr);
+
+  if (npart > 0) {
+    guint nmin = 1000;
+    guint mmax = 10000;
+    guint ntry = 10000;
+    guint np = bubble ? npart : pow (2., npart);
+    gfloat imbalance = 0.0;
+    GSList * partition, * i;
+    gint pid = 0;
+
+    if (verbose)
+      gts_graph_print_stats (GTS_GRAPH (simulation), stderr);
+    if (gts_container_size (GTS_CONTAINER (simulation)) < np) {
+      fprintf (stderr,
+	       "gerris: the number of boxes in the domain to partition should be >= %d\n"
+	       "Use option '-s' to split the domain first\n"
+	       "Try `gerris --help' for more information.\n",
+	       np);
+      return 1;
+    }
+    if (bubble)
+      partition = gts_graph_bubble_partition (GTS_GRAPH (simulation), npart, 100, 
+					      verbose ? 
+					      (GtsFunc) gts_graph_partition_print_stats : NULL, 
+					      stderr);
+    else
+      partition = gts_graph_recursive_bisection (GTS_WGRAPH (simulation),
+						 npart, 
+						 ntry, mmax, nmin, imbalance);
+
+    i = partition;
+    while (i) {
+      gts_container_foreach (GTS_CONTAINER (i->data), 
+			     (GtsFunc) set_box_pid, &pid);
+      pid++;
+      i = i->next;
+    }
+    if (verbose)
+      gts_graph_partition_print_stats (partition, stderr);
+    gts_graph_partition_destroy (partition);
+    gfs_simulation_write (simulation, maxlevel, stdout);
+    return 0;
+  }
+
+  domain = GFS_DOMAIN (simulation);
+  if (split) {
+    gfs_clock_start (domain->timer);
+    gfs_simulation_refine (simulation);
+    gfs_clock_stop (domain->timer);
+    while (split) {
+      gfs_domain_split (domain, one_box_per_pe);
+      split--;
+    }
+    gfs_simulation_write (simulation, maxlevel, stdout);
+    return 0;
+  }
+
+  if (events->len > 0) {
+    GSList * l = NULL;
+    guint i;
+    for (i = 0; i < events->len; i++) {
+      GtsFile * fp = gts_file_new_from_string (g_ptr_array_index (events, i));
+      if (fp->type != GTS_STRING) {
+	gfs_error (-1, 
+		   "gerris: invalid event: '%s'\n"
+		   "expecting a GfsEvent name\n",
+		   (char *) g_ptr_array_index (events, i));
+	return 1;
+      }
+      GtsObjectClass * klass = gfs_object_class_from_name (fp->token->str);
+      if (klass == NULL) {
+	gfs_error (-1, "gerris: unknown event class `%s'\n", fp->token->str);
+	return 1;
+      }
+      if (!gts_object_class_is_from_class (klass, gfs_event_class ())) {
+	gfs_error (-1, "gerris: class `%s' is not a GfsEvent\n", fp->token->str);
+	return 1;
+      }
+      GtsObject * object = gts_object_new (klass);
+      gfs_object_simulation_set (object, simulation);
+      g_assert (klass->read);
+      (* klass->read) (&object, fp);
+      if (fp->type == GTS_ERROR) {
+	gfs_error (-1,
+		   "gerris: invalid event: '%s'\n"
+		   "%d:%d: %s\n",
+		   (char *) g_ptr_array_index (events, i),
+		   fp->line, fp->pos, fp->error);
+	return 1;
+      }
+      if (GFS_IS_ADAPT (object))
+	gts_container_add (GTS_CONTAINER (simulation->adapts), GTS_CONTAINEE (object));
+      else if (GFS_IS_SOLID (object))
+	gts_container_add (GTS_CONTAINER (simulation->solids), GTS_CONTAINEE (object));
+      gts_container_add (GTS_CONTAINER (simulation->events), GTS_CONTAINEE (object));
+      l = g_slist_append (l, object);
+      gts_file_destroy (fp);
+    }
+    gfs_clock_start (domain->timer);
+    g_slist_foreach (l, (GFunc) gfs_event_do, simulation);    
+    gfs_clock_stop (domain->timer);
+    setup_binary_IO (domain);
+    gfs_simulation_write (simulation, -1, stdout);
+    return 0;
+  }
+
+  domain->profile_bc = profile;
+
+  gfs_simulation_run (simulation);
+
+  return 0;
+}
diff --git a/src/gerris2D.pc.in b/src/gerris2D.pc.in
new file mode 100644
index 0000000..6741d53
--- /dev/null
+++ b/src/gerris2D.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Gerris2D
+Description: Gerris Flow Solver Library (2D)
+Version: @VERSION@
+Requires: gts >= 0.7.3
+Libs: -L${libdir} -lgfs2D -lgts -lm
+Cflags: -I${includedir} -DFTT_2D=1
diff --git a/src/gerris2D3.pc.in b/src/gerris2D3.pc.in
new file mode 100644
index 0000000..fc2f41c
--- /dev/null
+++ b/src/gerris2D3.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Gerris2D3
+Description: Gerris Flow Solver Library (2D3)
+Version: @VERSION@
+Requires: gts >= 0.7.3
+Libs: -L${libdir} -lgfs2D3 -lgts -lm
+Cflags: -I${includedir} -DFTT_2D3=1
diff --git a/src/gerris3D.pc.in b/src/gerris3D.pc.in
new file mode 100644
index 0000000..548f692
--- /dev/null
+++ b/src/gerris3D.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Gerris3D
+Description: Gerris Flow Solver Library (3D)
+Version: @VERSION@
+Requires: gts >= 0.7.3
+Libs: -L${libdir} -lgfs3D -lgts -lm
+Cflags: -I${includedir}
diff --git a/src/gfs-config.in b/src/gfs-config.in
new file mode 100644
index 0000000..9dbc382
--- /dev/null
+++ b/src/gfs-config.in
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+gts_libs="@gts_libs@"
+gts_cflags="@gts_cflags@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+
+usage()
+{
+	cat <<EOF
+Usage: gfs-config [OPTIONS]
+Options:
+	[--prefix[=DIR]]
+	[--exec-prefix[=DIR]]
+	[--version]
+	[--libs]
+	[--cflags]
+        [--2D]
+EOF
+	exit $1
+}
+
+uniquify()
+{
+    echo $1 | awk '{
+	for (i = 1; i <= NF; i++) {
+	    unique = 1;
+	    for (j = i + 1; j <= NF && unique; j++)
+		if ($i == $j)
+		    unique = 0;
+            if (unique)
+		printf ("%s ", $i);
+	}
+    }'
+}
+
+if test $# -eq 0; then
+	usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo_exec_prefix=yes
+      ;;
+    --version)
+      echo @GFS_VERSION@
+      exit 0
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --2D)
+      twod=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "$echo_prefix" = "yes"; then
+	echo $prefix
+fi
+if test "$echo_exec_prefix" = "yes"; then
+	echo $exec_prefix
+fi
+if test "$echo_cflags" = "yes"; then
+	if test "$twod" = "yes"; then
+	    gts_cflags="$gts_cflags -DFTT_2D=1"
+	fi
+	gts_cflags="$gts_cflags -I${prefix}/include"
+	gts_cflags=`uniquify "$gts_cflags"`
+	echo $gts_cflags
+fi
+if test "$echo_libs" = "yes"; then
+	if test "$twod" = "yes"; then
+	    gts_libs="-L${exec_prefix}/lib -lgfs2D $gts_libs -lm"
+	else
+	    gts_libs="-L${exec_prefix}/lib -lgfs3D $gts_libs -lm"
+	fi
+	gts_libs=`uniquify "$gts_libs"`
+	echo $gts_libs
+fi
diff --git a/src/gfs.h b/src/gfs.h
new file mode 100644
index 0000000..2b956da
--- /dev/null
+++ b/src/gfs.h
@@ -0,0 +1,46 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GFS_H__
+#define __GFS_H__
+
+#include <gerris/ftt.h>
+#include <gerris/fluid.h>
+#include <gerris/output.h>
+#include <gerris/solid.h>
+#include <gerris/poisson.h>
+#include <gerris/advection.h>
+#include <gerris/boundary.h>
+#include <gerris/timestep.h>
+#include <gerris/domain.h>
+#include <gerris/init.h>
+#include <gerris/refine.h>
+#include <gerris/event.h>
+#include <gerris/simulation.h>
+#include <gerris/graphic.h>
+#include <gerris/adaptive.h>
+#include <gerris/source.h>
+#include <gerris/vof.h>
+#include <gerris/cartesian.h>
+#include <gerris/surface.h>
+#include <gerris/unstructured.h>
+#include <gerris/map.h>
+#include <gerris/version.h>
+
+#endif /* GFS_H */
diff --git a/src/gfsconfig.h b/src/gfsconfig.h
new file mode 100644
index 0000000..623af7a
--- /dev/null
+++ b/src/gfsconfig.h
@@ -0,0 +1,12 @@
+/* gfsconfig.h
+ *
+ * This is a generated file.  Please modify `configure.in'
+ */
+
+#ifndef GFSCONFIG_H
+#define GFSCONFIG_H
+
+#define GFS_HAS_MODULES 1
+
+
+#endif /* GFSCONFIG_H */
diff --git a/src/graphic.c b/src/graphic.c
new file mode 100644
index 0000000..ed3c354
--- /dev/null
+++ b/src/graphic.c
@@ -0,0 +1,2152 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <gts.h>
+
+#include "config.h"
+#include "graphic.h"
+#include "solid.h"
+#include "variable.h"
+#include "version.h"
+
+#if !FTT_2D
+#  include "isocube.h"
+#endif /* 3D */
+
+typedef struct {
+  GPtrArray * colors;
+  gboolean reversed;
+} Colormap;
+
+static GtsColor * color_new (gdouble r, gdouble g, gdouble b)
+{
+  GtsColor * c = g_malloc (sizeof (GtsColor));
+  c->r = r; c->g = g; c->b = b;
+  return c;
+}
+
+static void color_destroy (GtsColor * color)
+{
+  g_return_if_fail (color != NULL);
+
+  g_free (color);
+}
+
+static Colormap * colormap_jet (void)
+{
+  Colormap * cmap = g_malloc (sizeof (Colormap));
+  gint i;
+
+  cmap->reversed = FALSE;
+  cmap->colors = g_ptr_array_new ();
+  for (i = 0; i < 127; i++) {
+    gdouble r = 
+      i <= 46 ? 0. : 
+      i >= 111 ? -0.03125*(i - 111) + 1. :
+      i >= 78 ? 1. : 
+      0.03125*(i - 46);
+    gdouble g = 
+      i <= 14 || i >= 111 ? 0. : 
+      i >= 79 ? -0.03125*(i - 111) : 
+      i <= 46 ? 0.03125*(i - 14) : 
+      1.;
+    gdouble b =
+      i >= 79 ? 0. :
+      i >= 47 ? -0.03125*(i - 79) :
+      i <= 14 ? 0.03125*(i - 14) + 1.:
+      1.;
+
+    g_ptr_array_add (cmap->colors, color_new (r, g, b));
+  }
+  return cmap;
+}
+
+static void colormap_destroy (Colormap * colormap)
+{
+  guint i;
+
+  g_return_if_fail (colormap != NULL);
+
+  for (i = 0; i < colormap->colors->len; i++)
+    color_destroy (colormap->colors->pdata[i]);
+  g_ptr_array_free (colormap->colors, TRUE);
+  g_free (colormap);
+}
+
+static GtsColor colormap_color (Colormap * cmap, gdouble val)
+{
+  GtsColor c = {1., 1., 1.}, * c1, * c2;
+  guint i, n;
+  gdouble coef;
+
+  g_return_val_if_fail (cmap != NULL, c);
+
+  if (val > 1.0) val = 1.0;
+  else if (val < 0.0) val = 0.0;
+  if (cmap->reversed)
+    val = 1.0 - val;
+
+  n = cmap->colors->len;
+  if (n == 0)
+    return c;
+  if (n == 1)
+    return *((GtsColor *)cmap->colors->pdata[0]);
+
+  i = floor ((gdouble)val*(gdouble)(n - 1));
+  if (i == n - 1)
+    return *((GtsColor *)cmap->colors->pdata[cmap->colors->len - 1]);
+  coef = val*(gdouble)(n - 1) - (gdouble)i;
+  c1 = cmap->colors->pdata[i];
+  c2 = cmap->colors->pdata[i+1];
+  c.r = c1->r + coef*(c2->r - c1->r);
+  c.g = c1->g + coef*(c2->g - c1->g);
+  c.b = c1->b + coef*(c2->b - c1->b);
+  return c;
+}
+
+/* VertexCellFace: Header */
+
+typedef struct _VertexCellFace         VertexCellFace;
+
+struct _VertexCellFace {
+  /*< private >*/
+  GtsVertex parent;
+
+  /*< public >*/
+  guint index;
+  FttCell * cell;
+  FttCellFace face;
+};
+
+#define VERTEX_CELL_FACE(obj)            GTS_OBJECT_CAST (obj,\
+					         VertexCellFace,\
+					         vertex_cell_face_class ())
+
+/* VertexCellFace: Object */
+
+static GtsVertexClass * vertex_cell_face_class (void)
+{
+  static GtsVertexClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo vertex_cell_face_info = {
+      "VertexCellFace",
+      sizeof (VertexCellFace),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_vertex_class ()),
+				  &vertex_cell_face_info);
+  }
+
+  return klass;
+}
+
+static void triangulate (FttCell * cell, gpointer * data)
+{
+  GtsSurface * s = data[0];
+  GfsVariable * var = data[1];
+  GtsVertex * v;
+  FttVector pos;
+
+  if (var && var->centered)
+    ftt_cell_pos (cell, &pos);
+  else 
+    gfs_cell_cm (cell, &pos);
+
+  v = gts_vertex_new (s->vertex_class, pos.x, pos.y, pos.z);
+  if (var) {
+    GtsMatrix * transform = data[2];
+    gdouble * z = data[3];
+    GfsNorm * norm = data[4];
+
+    gts_point_transform (GTS_POINT (v), transform);
+    GTS_POINT (v)->z = *z + GFS_VARIABLE (cell, var->i)/(norm->infty*1000.);
+  }
+  g_assert (gts_delaunay_add_vertex (s, v, NULL) == NULL);
+  VERTEX_CELL_FACE (v)->cell = cell;
+}
+
+static void triangulate_face (FttCell * cell, gpointer * data)
+{
+  GtsSurface * s = data[0];
+  GfsVariable * var = data[1];
+  FttDirection * d = data[5];
+  GtsVertex * v;
+  FttVector pos;
+  FttCellFace face;
+
+  face.cell = cell;
+  face.d = *d;
+  face.neighbor = ftt_cell_neighbor (cell, face.d);
+  ftt_face_pos (&face, &pos);
+  v = gts_vertex_new (s->vertex_class, pos.x, pos.y, pos.z);
+  if (var) {
+    GtsMatrix * transform = data[2];
+    gdouble * z = data[3];
+    GfsNorm * norm = data[4];
+
+    gts_point_transform (GTS_POINT (v), transform);
+    if (face.neighbor)
+      GTS_POINT (v)->z = *z + 
+	gfs_face_interpolated_value  (&face, var->i)/(norm->infty*1000.);
+    else
+      GTS_POINT (v)->z = *z + GFS_VARIABLE (cell, var->i)/(norm->infty*1000.);
+  }
+  g_assert (gts_delaunay_add_vertex (s, v, NULL) == NULL);
+  VERTEX_CELL_FACE (v)->face = face;
+}
+
+static void add_long_segment (GtsSegment * s, GSList ** list)
+{
+  FttCell * c1 = VERTEX_CELL_FACE (s->v1)->cell ? VERTEX_CELL_FACE (s->v1)->cell :
+    VERTEX_CELL_FACE (s->v1)->face.cell;
+  FttCell * c2 = VERTEX_CELL_FACE (s->v2)->cell ? VERTEX_CELL_FACE (s->v2)->cell :
+    VERTEX_CELL_FACE (s->v2)->face.cell;
+  gdouble s1 = ftt_cell_size (c1);
+  gdouble s2 = ftt_cell_size (c2);
+  gdouble size = MIN (s1, s2);
+
+  if (gts_point_distance2 (GTS_POINT (s->v1), GTS_POINT (s->v2)) > 
+      16.*size*size)
+    *list = g_slist_prepend (*list, s);
+}
+
+void gfs_write_gts (GfsDomain * domain, 
+		    GfsVariable * v, 
+		    FttTraverseFlags flags,
+		    gint level,
+		    GtsBBox * box,
+		    FILE * fp)
+{
+  GtsSurface * s;
+  GtsVertex * v1, * v2, * v3;
+  GtsEdge * e1, * e2, * e3;
+  gpointer data[6];
+  GtsMatrix * transform, * inv;
+  gdouble z = 0.;
+  GfsNorm norm;
+  GSList * long_segments = NULL;
+
+  g_return_if_fail (domain != NULL);
+#if (!FTT_2D)
+  g_return_if_fail (box != NULL);
+#endif /* 3D */
+  g_return_if_fail (fp != NULL);
+
+  v1 = gts_vertex_new (gts_vertex_class (), -100., -100., 0.);
+  v2 = gts_vertex_new (gts_vertex_class (), 100., -100., 0.);
+  v3 = gts_vertex_new (gts_vertex_class (), 0., 100., 0.);
+  e1 = gts_edge_new (gts_edge_class (), v1, v2);
+  e2 = gts_edge_new (gts_edge_class (), v2, v3);
+  e3 = gts_edge_new (gts_edge_class (), v3, v1);
+  s = gts_surface_new (gts_surface_class (), 
+		       gts_face_class (), 
+		       gts_edge_class (), 
+		       vertex_cell_face_class ());
+  gts_surface_add_face (s, gts_face_new (gts_face_class (), e1, e2, e3));
+
+  norm = gfs_domain_norm_variable (domain, v, NULL, flags, level);
+  if (norm.infty == 0.)
+    norm.infty = 1.;
+#if FTT_2D
+  transform = gts_matrix_identity (NULL);
+#else /* 3D */
+  if (box->x2 - box->x1 < box->z2 - box->z1 &&
+      box->x2 - box->x1 < box->y2 - box->y1) {
+    z = box->x2 = box->x1 = (box->x2 + box->x1)/2. + 1e-30;
+    transform = gts_matrix_new (0., 1., 0., 0.,
+				0., 0., 1., 0.,
+				1., 0., 0., 0.,
+				0., 0., 0., 0.);
+  }
+  else if (box->y2 - box->y1 < box->z2 - box->z1 &&
+	   box->y2 - box->y1 < box->x2 - box->x1) {
+    z = box->y2 = box->y1 = (box->y2 + box->y1)/2. + 1e-30;
+    transform = gts_matrix_new (0., 0., 1., 0.,
+				1., 0., 0., 0.,
+				0., 1., 0., 0.,
+				0., 0., 0., 0.);
+  }
+  else {
+    z = box->z2 = box->z1 = (box->z2 + box->z1)/2. + 1e-30;
+    transform = gts_matrix_new (1., 0., 0., 0.,
+				0., 1., 0., 0.,
+				0., 0., 1., 0.,
+				0., 0., 0., 0.);
+  }
+#endif /* 3D */
+  
+  data[0] = s;
+  data[1] = v;
+  data[2] = transform;
+  data[3] = &z;
+  data[4] = &norm;
+  if (box == NULL) {
+    FttDirection d;
+
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, level, 
+			     (FttCellTraverseFunc) triangulate, data);
+    data[5] = &d;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      gfs_domain_cell_traverse_boundary (domain, d, 
+					 FTT_PRE_ORDER, flags, level, 
+		   (FttCellTraverseFunc) triangulate_face, data);
+  }
+  else
+    gfs_domain_cell_traverse_box (domain, box, FTT_PRE_ORDER, flags, level, 
+				 (FttCellTraverseFunc) triangulate, data);
+
+  gts_allow_floating_vertices = TRUE;
+  gts_object_destroy (GTS_OBJECT (v1));
+  gts_object_destroy (GTS_OBJECT (v2));
+  gts_object_destroy (GTS_OBJECT (v3));
+  gts_allow_floating_vertices = FALSE;
+
+  gts_surface_foreach_edge (s, (GtsFunc) add_long_segment, &long_segments);
+  gts_allow_floating_edges = TRUE;
+  g_slist_foreach (long_segments, (GFunc) gts_object_destroy, NULL);
+  gts_allow_floating_edges = FALSE;
+  g_slist_free (long_segments);
+
+  inv = gts_matrix3_inverse (transform);
+  gts_matrix_destroy (transform);
+  transform = inv;
+  gts_surface_foreach_vertex (s, (GtsFunc) gts_point_transform, transform);
+  gts_surface_write (s, fp);
+
+  gts_object_destroy (GTS_OBJECT (s));
+  gts_matrix_destroy (transform);
+}
+
+static void extent (FttCell * cell, gpointer * data)
+{
+  FttVector * min = data[0];
+  FttVector * max = data[1];
+  FttVector pos;
+  
+  ftt_cell_pos (cell, &pos);
+  if (pos.x > max->x) max->x = pos.x;
+  if (pos.y > max->y) max->y = pos.y;
+  if (pos.z > max->z) max->z = pos.z;
+  if (pos.x < min->x) min->x = pos.x;
+  if (pos.y < min->y) min->y = pos.y;
+  if (pos.z < min->z) min->z = pos.z;
+}
+
+static void iso_func (gdouble ** a, GtsCartesianGrid g, guint k,
+		      gpointer * data)
+{
+  GfsDomain * domain = data[0];
+  guint * level = data[1], i, j;
+  GfsVariable * v = data[2];
+  FttVector p;
+  fprintf (stderr, "\rslice %4d/%d", k + 1, g.nz);
+  p.z = g.z;
+  for (i = 0, p.x = g.x; i < g.nx; i++, p.x += g.dx)
+    for (j = 0, p.y = g.y; j < g.ny; j++, p.y += g.dy) {
+      FttCell * cell = gfs_domain_locate (domain, p, *level, NULL);
+
+      if (cell == NULL)
+	a[i][j] = 0.;
+      else
+	a[i][j] = gfs_interpolate (cell, p, v);
+    }
+}
+
+GtsSurface * gfs_isosurface (GfsDomain * domain, 
+			     GfsVariable * v, gdouble val,
+			     gint level)
+{
+  FttVector cmax = { - G_MAXDOUBLE, - G_MAXDOUBLE, - G_MAXDOUBLE };
+  FttVector cmin = { G_MAXDOUBLE, G_MAXDOUBLE, G_MAXDOUBLE };
+  guint depth;
+  GtsCartesianGrid g;
+  gpointer data[3];
+  GtsSurface * s;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (v != NULL, NULL);
+
+  if (level < 0)
+    depth = gfs_domain_depth (domain);
+  else
+    depth = level;
+
+  data[0] = &cmin;
+  data[1] = &cmax;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+			    FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, depth,
+			    (FttCellTraverseFunc) extent, data);
+  if (cmin.x == G_MAXDOUBLE)
+    return NULL;
+
+  g.dx = g.dy = g.dz = ftt_level_size (depth);
+  g.x = cmin.x; g.y = cmin.y; g.z = cmin.z;
+  g.nx = (cmax.x - cmin.x)/g.dx + 1;
+  g.ny = (cmax.y - cmin.y)/g.dy + 1;
+  g.nz = (cmax.z - cmin.z)/g.dz + 1;
+  
+  s = gts_surface_new (gts_surface_class (), 
+		       gts_face_class (), 
+		       gts_edge_class (), 
+		       gts_vertex_class ());
+  data[0] = domain;
+  data[1] = &depth;
+  data[2] = v;
+  gts_isosurface_cartesian (s, g, (GtsIsoCartesianFunc) iso_func, data, val);
+
+  return s;
+}
+
+static void write_gnuplot (FttCell * cell, gpointer * data)
+{
+  FILE * fp = data[0];
+  GfsVariable * v = data[1];
+  GtsBBox * bbox = data[2];
+  FttVector pos;
+  
+  if (v->centered)
+    ftt_cell_pos (cell, &pos);
+  else
+    gfs_cell_cm (cell, &pos);
+
+  if (bbox == NULL || (pos.x >= bbox->x1 && pos.x <= bbox->x2 &&
+		       pos.y >= bbox->y1 && pos.y <= bbox->y2 &&
+		       pos.z >= bbox->z1 && pos.z <= bbox->z2)) {
+    gfs_simulation_map_inverse (GFS_SIMULATION (v->domain), &pos);
+    fprintf (fp, "%g %g %g %g\n", 
+	     pos.x, pos.y, pos.z, GFS_VARIABLE (cell, v->i));
+  }
+}
+
+void gfs_write_gnuplot (GfsDomain * domain, 
+			GfsVariable * v, 
+			FttTraverseFlags flags,
+			gint level,
+			GtsBBox * bbox,
+			FILE * fp)
+{  
+  gpointer data[3];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  data[0] = fp;
+  data[1] = v;
+  data[2] = bbox;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, level, 
+			   (FttCellTraverseFunc) write_gnuplot, data);
+}
+
+typedef struct {
+  guchar r, g, b;
+} Color;
+
+typedef struct {
+  FttVector min;
+  guint width, height, size;
+  guchar * buf, *** data;
+} Image;
+
+static Image * image_new (FttVector min, FttVector max, guint size)
+{
+  Image * im = g_malloc0 (sizeof (Image));
+  guint i;
+
+  im->min = min;
+  im->size = size;
+  im->width = (max.x - min.x)*size;
+  im->height = (max.y - min.y)*size;
+  im->buf = g_malloc0 (sizeof (guchar)*3*im->width*im->height);
+  im->data = g_malloc (sizeof (guchar **)*im->height);
+  for (i = 0; i < im->height; i++) {
+    guint j;
+
+    im->data[i] = g_malloc (sizeof (guchar *)*im->width);
+    for (j = 0; j < im->width; j++)
+      im->data[i][j] = &im->buf[3*(i*im->width + j)];
+  }
+  return im;
+}
+
+static void image_write (Image * im, FILE * fp)
+{
+  fprintf (fp, 
+	   "P6\n"
+	   "# File generated by gerris using 2D libgfs version %s (%s)\n"
+	   "# Origin: %d %d\n"
+	   "%u %u 255\n",
+	   GFS_VERSION,
+	   GFS_BUILD_VERSION,
+	   (gint) (im->min.x*im->size), 
+	   (gint) (im->min.y*im->size),
+	   im->width, im->height);
+  fwrite (im->buf, sizeof (guchar), 3*im->width*im->height, fp);
+}
+
+static void image_destroy (Image * im)
+{
+  guint i;
+
+  for (i = 0; i < im->height; i++)
+    g_free (im->data[i]);
+  g_free (im->data);
+  g_free (im->buf);
+  g_free (im);
+}
+
+static void image_draw_square (Image * im,
+			       FttVector * p1, FttVector * p2,
+			       Color c)
+{
+  gint i1, j1, i2, j2, i, j;
+
+  i1 = (p1->x - im->min.x)*im->size;
+  i2 = (p2->x - im->min.x)*im->size;
+  j1 = (p1->y - im->min.y)*im->size;
+  j2 = (p2->y - im->min.y)*im->size;
+
+  j1 = im->height - 1 - j1;
+  j2 = im->height - 1 - j2;
+  for (i = i1; i <= i2; i++)
+    for (j = j2; j <= j1; j++) 
+      if (i >= 0 && i < im->width && j >= 0 && j < im->height) {
+	im->data[j][i][0] = c.r;
+	im->data[j][i][1] = c.g;
+	im->data[j][i][2] = c.b;
+      }
+}
+
+static void write_image_square (FttCell * cell, gpointer * data)
+{
+  Colormap * colormap = data[0];
+  gdouble * min = data[1];
+  gdouble * max = data[2];
+  GfsVariable * v = data[3];
+  Image * image = data[4];
+  FttVector * lambda = data[5];
+  FttVector p;
+  GtsColor fc = colormap_color (colormap, (GFS_VARIABLE (cell, v->i) - *min)/(*max - *min));
+  Color c;
+  gdouble size = ftt_cell_size (cell)/2.;
+  FttVector p1, p2;
+
+  ftt_cell_pos (cell, &p);
+  c.r = fc.r*255;
+  c.g = fc.g*255;
+  c.b = fc.b*255;
+  p1.x = (p.x - size)/lambda->x + 1e-9;
+  p1.y = (p.y - size)/lambda->y + 1e-9;
+  p2.x = (p.x + size)/lambda->x - 1e-9;
+  p2.y = (p.y + size)/lambda->y - 1e-9;
+  image_draw_square (image, &p1, &p2, c);
+}
+
+static void max_extent (FttCell * cell, FttVector * max)
+{
+  FttVector pos;
+  
+  ftt_cell_pos (cell, &pos);
+  if (pos.x > max->x) max->x = pos.x;
+  if (pos.y > max->y) max->y = pos.y;
+  if (pos.z > max->z) max->z = pos.z;
+}
+
+static void min_extent (FttCell * cell, FttVector * min)
+{
+  FttVector pos;
+  
+  ftt_cell_pos (cell, &pos);
+  if (pos.x < min->x) min->x = pos.x;
+  if (pos.y < min->y) min->y = pos.y;
+  if (pos.z < min->z) min->z = pos.z;
+}
+
+void gfs_write_ppm (GfsDomain * domain, 
+		    GtsBBox * box,
+		    GfsVariable * v, gdouble min, gdouble max,
+		    FttTraverseFlags flags,
+		    gint level,
+		    FILE * fp)
+{
+  Colormap * colormap;
+  guint depth, size = 1;
+  Image * image;
+  FttVector cmax = { - G_MAXDOUBLE, - G_MAXDOUBLE, - G_MAXDOUBLE };
+  FttVector cmin = { G_MAXDOUBLE, G_MAXDOUBLE, G_MAXDOUBLE };
+  gpointer data[6];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (min == max)
+    max = min + 1.;
+  if (level < 0)
+    depth = gfs_domain_depth (domain);
+  else
+    depth = level;
+  while (depth-- > 0)
+    size *= 2;
+
+  if (box != NULL) {
+    cmin.x = box->x1/domain->lambda.x; 
+    cmin.y = box->y1/domain->lambda.y; 
+    cmin.z = box->z1;
+    cmax.x = box->x2/domain->lambda.x; 
+    cmax.y = box->y2/domain->lambda.y; 
+    cmax.z = box->z2;
+  }
+  else {
+    gdouble h;
+
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, 
+			      domain->rootlevel,
+			      (FttCellTraverseFunc) min_extent, &cmin);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL,
+			      domain->rootlevel,
+			      (FttCellTraverseFunc) max_extent, &cmax);
+    if (cmin.x == G_MAXDOUBLE)
+      return;
+    h = ftt_level_size (domain->rootlevel)/2.;
+    cmin.x = (cmin.x - h)/domain->lambda.x; 
+    cmin.y = (cmin.y - h)/domain->lambda.y;
+    cmax.x = (cmax.x + h)/domain->lambda.x; 
+    cmax.y = (cmax.y + h)/domain->lambda.y;
+  }
+
+  colormap = colormap_jet ();
+  image = image_new (cmin, cmax, size);
+
+  data[0] = colormap;
+  data[1] = &min;
+  data[2] = &max;
+  data[3] = v;
+  data[4] = image;
+  data[5] = &domain->lambda;
+  if (box != NULL)
+    gfs_domain_cell_traverse_box (domain, box, FTT_PRE_ORDER, flags, level,
+				  (FttCellTraverseFunc) write_image_square, data);
+  else
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, level,
+			      (FttCellTraverseFunc) write_image_square, data);
+  image_write (image, fp);
+  image_destroy (image);
+  colormap_destroy (colormap);
+}
+
+static gint gfs_combine_close (FILE ** f, Image ** im, gint n, gint ret)
+{
+  guint i;
+
+  for (i = 0; i < n; i++) {
+    if (f[i])
+      fclose (f[i]);
+    if (im[i])
+      image_destroy (im[i]);
+  }
+  g_free (f);
+  g_free (im);
+  return ret;
+}
+
+static gint get_newline (FILE * fp)
+{
+  gint c;
+
+  c = fgetc (fp);
+  while (c != EOF && c != '\n')
+    c = fgetc (fp);
+  return c;
+}
+
+gint gfs_combine_ppm (gchar ** fname, guint nname, FILE * fp)
+{
+  FILE ** f;
+  guint i;
+  Image ** image;
+
+  g_return_val_if_fail (fname != NULL, 0);
+  g_return_val_if_fail (fp != NULL, 0);
+
+  f = g_malloc0 (nname*sizeof (FILE *));
+  image = g_malloc0 (nname*sizeof (Image *));
+  for (i = 0; i < nname; i++) {
+    f[i] = fopen (fname[i], "r");
+    if (f[i] == NULL)
+      return gfs_combine_close (f, image, nname, i);
+  }
+  
+  while (TRUE) {
+    gint x0 = G_MAXINT, y0 = G_MAXINT, x1 = - G_MAXINT, y1 = - G_MAXINT;
+    FttVector min, max;
+    Image * combo;
+
+    for (i = 0; i < nname; i++) {
+      gchar s[80];
+      gint x, y;
+      gint h, w;
+      guint status;
+
+      status = fscanf (f[i], "%79s", s);
+      if (status != 1 && feof (f[i]))
+	return gfs_combine_close (f, image, nname, -1);
+      if (status != 1 ||
+	  strcmp (s, "P6") ||
+	  get_newline (f[i]) == EOF ||
+	  get_newline (f[i]) == EOF ||
+	  fscanf (f[i], "%*s %79s %d %d", s, &x, &y) != 3 ||
+	  strcmp (s, "Origin:") ||
+	  fscanf (f[i], "%d %d", &w, &h) != 2)
+	return gfs_combine_close (f, image, nname, i);
+      if (x < x0) x0 = x;
+      if (y < y0) y0 = y;
+      if (x + w > x1) x1 = x + w;
+      if (y + h > y1) y1 = y + h;
+      min.x = x;
+      min.y = y;
+      max.x = x + w;
+      max.y = y + h;
+      if (image[i] != NULL)
+	image_destroy (image[i]);
+      image[i] = image_new (min, max, 1);
+      if (get_newline (f[i]) == EOF ||
+	  fread (image[i]->buf, sizeof (guchar), 
+		 3*image[i]->width*image[i]->height, f[i]) !=
+	  3*image[i]->width*image[i]->height)
+	return gfs_combine_close (f, image, nname, i);
+    }
+
+    min.x = x0;
+    min.y = y0;
+    max.x = x1;
+    max.y = y1;
+    combo = image_new (min, max, 1);
+    for (i = 0; i < nname; i++) {
+      guint x, y;
+
+      for (y = 0; y < image[i]->height; y++)
+	for (x = 0; x < image[i]->width; x++) {
+	  gint x1 = x + image[i]->min.x - combo->min.x;
+	  gint y1 = y + combo->min.y + combo->height - image[i]->min.y - image[i]->height;
+	  guchar r = image[i]->data[y][x][0];
+	  guchar g = image[i]->data[y][x][1];
+	  guchar b = image[i]->data[y][x][2];
+
+	  if (r || g || b) {
+	    combo->data[y1][x1][0] = r;
+	    combo->data[y1][x1][1] = g;
+	    combo->data[y1][x1][2] = b;
+	  }
+	}
+    }
+    image_write (combo, fp);
+    image_destroy (combo);
+  }
+  gfs_combine_close (f, image, nname, 0);
+}
+
+static void write_square (FttCell * cell, gpointer * data)
+{
+  Colormap * colormap = data[0];
+  gdouble * min = data[1];
+  gdouble * max = data[2];
+  GfsVariable * v = data[3];
+  FILE * fp = data[4];
+  FttVector p;
+  GtsColor c;
+  gdouble size = ftt_cell_size (cell)/2.;
+
+  ftt_cell_pos (cell, &p);
+  c = colormap_color (colormap, 
+		      (GFS_VARIABLE (cell, v->i) - *min)/(*max - *min));
+#if FTT_2D    
+  fprintf (fp, 
+	   "OFF 4 1 4\n"
+	   "%g %g 0\n%g %g 0\n%g %g 0\n%g %g 0\n"
+	   "5 0 1 2 3 0 %g %g %g\n",
+	   p.x - size, p.y - size,
+	   p.x + size, p.y - size,
+	   p.x + size, p.y + size,
+	   p.x - size, p.y + size,
+	   c.r, c.g, c.b);
+#else  /* FTT_3D */
+  fprintf (fp, 
+	   "OFF 8 6 12\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "%g %g %g\n"
+	   "4 3 2 1 0 %g %g %g\n"
+	   "4 4 5 6 7 %g %g %g\n"
+	   "4 2 3 7 6 %g %g %g\n"
+	   "4 0 1 5 4 %g %g %g\n"
+	   "4 0 4 7 3 %g %g %g\n"
+	   "4 1 2 6 5 %g %g %g\n",
+	   p.x - size, p.y - size, p.z - size,
+	   p.x + size, p.y - size, p.z - size,
+	   p.x + size, p.y + size, p.z - size,
+	   p.x - size, p.y + size, p.z - size,
+	   p.x - size, p.y - size, p.z + size,
+	   p.x + size, p.y - size, p.z + size,
+	   p.x + size, p.y + size, p.z + size,
+	   p.x - size, p.y + size, p.z + size,
+	   c.r, c.g, c.b,
+	   c.r, c.g, c.b,
+	   c.r, c.g, c.b,
+	   c.r, c.g, c.b,
+	   c.r, c.g, c.b,
+	   c.r, c.g, c.b);
+#endif /* FTT_3D */
+}
+
+void gfs_write_squares (GfsDomain * domain, 
+			GfsVariable * v, gdouble min, gdouble max,
+			FttTraverseFlags flags,
+			gint level,
+			GtsBBox * bbox,
+			FILE * fp)
+{
+  Colormap * colormap;
+  gpointer data[5];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (min == max)
+    max = min + 1.;
+  fputs ("LIST{\n", fp);
+  colormap = colormap_jet ();
+  data[0] = colormap;
+  data[1] = &min;
+  data[2] = &max;
+  data[3] = v;
+  data[4] = fp;  
+  if (bbox == NULL)
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, level,
+			     (FttCellTraverseFunc) write_square, data);
+  else
+    gfs_domain_cell_traverse_box (domain, bbox, FTT_PRE_ORDER, flags, level,
+			     (FttCellTraverseFunc) write_square, data);
+  fputs ("}\n", fp);
+  colormap_destroy (colormap);
+}
+
+static void write_mac (FttCellFace * face, gpointer * data)
+{
+  gdouble * scale = data[0];
+  FILE * fp = data[1];
+  GtsBBox * bbox = data[2];
+  FttVector p;
+
+  ftt_face_pos (face, &p);
+  if (bbox == NULL || (p.x >= bbox->x1 && p.x <= bbox->x2 &&
+		       p.y >= bbox->y1 && p.y <= bbox->y2 &&
+		       p.z >= bbox->z1 && p.z <= bbox->z2)) {
+    FttVector f = {0., 0., 0.};
+    gdouble un = GFS_FACE_NORMAL_VELOCITY (face)*(*scale);
+    FttComponent c = face->d/2;
+
+    switch (c) {
+    case FTT_X: f.x = un; break;
+    case FTT_Y: f.y = un; break;
+#if (!FTT_2D)
+    case FTT_Z: f.z = un; break;
+#endif /* not FTT_2D */
+    default: g_assert_not_reached ();
+    }
+    fprintf (fp, "%g %g %g\n%g %g %g\n%g %g %g\n\n",
+	     p.x + f.x - (f.x - f.y/2.)/5.,
+	     p.y + f.y - (f.x/2. + f.y)/5.,
+	     p.z + f.z,
+	     p.x + f.x,
+	     p.y + f.y,
+	     p.z + f.z,
+	     p.x + f.x - (f.x + f.y/2.)/5.,
+	     p.y + f.y + (f.x/2. - f.y)/5.,
+	     p.z + f.z);
+    fprintf (fp, "%g %g %g\n%g %g %g\n\n",
+	     p.x, p.y, p.z,
+	     p.x + f.x,
+	     p.y + f.y,
+	     p.z + f.z);
+  }
+}
+
+void gfs_write_mac_velocity (GfsDomain * domain,
+			     gdouble scale,
+			     FttTraverseFlags flags,
+			     gint level,
+			     GtsBBox * bbox,
+			     FILE * fp)
+{
+  gpointer data[3];
+  GfsNorm norm;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  norm = gfs_domain_norm_velocity (domain, flags, level);
+  scale = norm.infty > 0. ? 
+    ftt_level_size (level < 0 ? gfs_domain_depth (domain) : level)*
+    scale/norm.infty : scale;
+  data[0] = &scale;
+  data[1] = fp;
+  data[2] = bbox;
+  gfs_domain_face_traverse (domain, FTT_XYZ, FTT_PRE_ORDER, flags, level,
+			   (FttFaceTraverseFunc) write_mac, data);
+}
+
+void gfs_draw_cells (FttCell * cell, 
+		     FttTraverseFlags flags,
+		     gint level,
+		     FILE * fp)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "LIST {\n");
+  ftt_cell_traverse (cell, FTT_PRE_ORDER, flags, level,
+		     (FttCellTraverseFunc) ftt_cell_draw, fp);
+  fprintf (fp, "}\n");
+}
+
+void gfs_draw_levels (FttCell * cell, FILE * fp)
+{
+  guint l, depth;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (fp != NULL);
+
+  depth = ftt_cell_depth (cell);
+  for (l = 0; l <= depth; l++) {
+    fprintf (fp, "(geometry \"level %d\" { = ", l);
+    gfs_draw_cells (cell, FTT_TRAVERSE_LEVEL, l, fp);
+    fputs ("})\n", fp);
+  }
+}
+
+static void draw_box_boundaries (GfsBox * box, FILE * fp)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    GtsObject * o =  box->neighbor[d];
+
+    if (GFS_IS_BOUNDARY (o)) {
+      if (o->klass->color) {
+	GtsColor c = (* o->klass->color) (o);
+
+#if FTT_2D
+	fprintf (fp, "appearance { material { edgecolor %g %g %g } }\n", 
+		 c.r, c.g, c.b);
+#else /* 3D */
+	fprintf (fp, 
+	  "appearance { material { ambient %g %g %g diffuse %g %g %g } }\n",
+		 c.r, c.g, c.b, c.r, c.g, c.b);
+#endif /* 3D */	
+      }
+      fputs ("LIST {\n", fp);
+      ftt_face_traverse_boundary (box->root, d, 
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, 
+				  (FttFaceTraverseFunc) ftt_face_draw, fp);
+      fputs ("}\n", fp);
+    }
+    else if (GFS_IS_BOX (o) && box->pid != GFS_BOX (o)->pid) {
+#if FTT_2D
+      fputs ("appearance { material { edgecolor 1 0 0 } }\n", fp);
+#else /* 3D */
+      fputs ("appearance { material { ambient 1 0 0 diffuse 1 0 0 } }\n", fp);
+#endif /* 3D */
+      fputs ("LIST {\n", fp);
+      ftt_face_traverse_boundary (box->root, d, 
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, 
+				  (FttFaceTraverseFunc) ftt_face_draw, fp);
+      fputs ("}\n", fp);
+    }
+  }
+}
+
+/**
+ * gfs_draw_boundary_conditions:
+ * @domain: a fluid domain.
+ * @fp: a file pointer.
+ *
+ * Outputs in @fp an OOGL (geomview) representation of the boundary
+ * conditions of the domain.  
+ */
+void gfs_draw_boundary_conditions (GfsDomain * domain, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fputs ("(geometry \"conditions\" = \n"
+	 "LIST {\n", fp);
+#if FTT_2D
+  fputs ("appearance { linewidth 2 }\n", fp);
+#endif /* 2D */
+  gts_container_foreach (GTS_CONTAINER (domain), 
+			 (GtsFunc) draw_box_boundaries, fp);
+  fputs ("})\n", fp);
+}
+
+static void draw_boundary_face (FttCell * cell, FILE * fp)
+{
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    FttCellFace face = ftt_cell_face (cell, d);
+
+    if (ftt_face_type (&face) == FTT_BOUNDARY)
+      ftt_face_draw (&face, fp);
+  }
+}
+
+/**
+ * gfs_draw_solid_boundaries:
+ * @domain: a fluid domain.
+ * @fp: a file pointer.
+ *
+ * Outputs in @fp an OOGL (geomview) representation of the solid boundaries
+ * of the domain.
+ */
+void gfs_draw_solid_boundaries (GfsDomain * domain, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fputs ("(geometry \"solid\" = {\n", fp);
+#if FTT_2D
+  fputs ("appearance { linewidth 2 }\n", fp);
+#endif /* 2D */
+  fputs ("LIST{\n", fp);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			   (FttCellTraverseFunc) draw_boundary_face, fp);
+  fputs ("}})\n", fp);
+}
+
+static void count_face (FttCell * cell, guint * count)
+{
+  if (FTT_CELL_IS_LEAF (cell)) {
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++) {
+      FttCellFace face = ftt_cell_face (cell, d);
+      
+      if (ftt_face_type (&face) == FTT_FINE_COARSE && face.cell == cell)
+	(*count)++;
+    }
+  }
+}
+
+static void draw_face (FttCell * cell, FILE * fp)
+{
+  if (FTT_CELL_IS_LEAF (cell)) {
+    FttDirection d;
+    
+    for (d = 0; d < FTT_NEIGHBORS; d++) {
+      FttCellFace face = ftt_cell_face (cell, d);
+      
+      if (ftt_face_type (&face) == FTT_FINE_COARSE && face.cell == cell)
+	ftt_face_draw (&face, fp);
+    }
+  }
+}
+
+/**
+ * gfs_draw_refined_boundaries:
+ * @domain: a fluid domain.
+ * @fp: a file pointer.
+ *
+ * Outputs in @fp an OOGL (geomview) representation of the boundaries
+ * of the refined domains.
+ */
+void gfs_draw_refined_boundaries (GfsDomain * domain, FILE * fp)
+{
+  guint depth, level;
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  depth = gfs_domain_depth (domain);
+  for (level = 1; level <= depth; level++) {
+    guint count = 0;
+
+    gfs_domain_cell_traverse (domain, 
+			     FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, level,
+			     (FttCellTraverseFunc) count_face, &count);
+    if (count > 0) {
+      fprintf (fp, "(geometry \"refine_%u_%u\" = \n", level - 1, level);
+      fputs ("LIST{\n", fp);
+      gfs_domain_cell_traverse (domain, 
+			       FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, level,
+			       (FttCellTraverseFunc) draw_face, fp);
+      fputs ("}\n)\n", fp);
+    }
+  }
+}
+
+static gpointer color_data[5];
+
+static GtsColor variable_color (GtsObject * o)
+{
+  GfsDomain * domain = color_data[0];
+  GfsVariable * v = color_data[1];
+  Colormap * colormap = color_data[2];
+  gdouble * min = color_data[3];
+  gdouble * max = color_data[4];
+  FttCell * cell;
+
+  GtsPoint * p = GTS_POINT (o);
+  FttVector pos;
+  gdouble val;
+  GtsColor c;
+
+  pos.x = p->x;
+  pos.y = p->y;
+  pos.z = p->z;
+
+  cell = gfs_domain_locate (domain, pos, -1, NULL);
+  if (cell) {
+    val = gfs_interpolate (cell, pos, v);
+    c = colormap_color (colormap, (val - *min)/(*max - *min));
+  }
+  else
+    c.r = c.g = c.b = 1.;
+  return c;
+}
+
+void gfs_draw_surface (GfsDomain * domain,
+		       GtsSurface * s,
+		       GfsVariable * v, 
+		       gdouble min, gdouble max,
+		       FILE * fp)
+{
+  GtsColor (*old_color) (GtsObject *);
+  Colormap * colormap;
+
+  g_return_if_fail (domain != NULL);  
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (fp != NULL);
+
+  gfs_domain_cell_traverse (domain, 
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) v->fine_coarse, v);
+  if (min == max)
+    max = min + 1.;
+  colormap = colormap_jet ();
+  old_color = GTS_OBJECT_CLASS (s->vertex_class)->color;
+  GTS_OBJECT_CLASS (s->vertex_class)->color = variable_color;
+  color_data[0] = domain;
+  color_data[1] = v;
+  color_data[2] = colormap;
+  color_data[3] = &min;
+  color_data[4] = &max;
+  gts_surface_write_oogl (s, fp);
+  GTS_OBJECT_CLASS (s->vertex_class)->color = old_color;
+
+  colormap_destroy (colormap);
+}
+
+/* GtsColoredVertex: Header */
+
+typedef struct _GtsColoredVertex         GtsColoredVertex;
+
+struct _GtsColoredVertex {
+  /*< private >*/
+  GtsVertex parent;
+
+  /*< public >*/
+  GtsColor c;
+};
+
+#define GTS_COLORED_VERTEX(obj)            GTS_OBJECT_CAST (obj,\
+					         GtsColoredVertex,\
+					         gts_colored_vertex_class ())
+#define GTS_IS_COLORED_VERTEX(obj)         (gts_object_is_from_class (obj,\
+						 gts_colored_vertex_class ()))
+
+GtsVertexClass * gts_colored_vertex_class  (void);
+
+/* GtsColoredVertex: Object */
+
+static void gts_colored_vertex_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (c.r)");
+    return;
+  }
+  GTS_COLORED_VERTEX (*o)->c.r = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (c.g)");
+    return;
+  }
+  GTS_COLORED_VERTEX (*o)->c.g = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (c.b)");
+    return;
+  }
+  GTS_COLORED_VERTEX (*o)->c.b = atof (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void gts_colored_vertex_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->write) 
+      (o, fp);
+  fprintf (fp, " %g %g %g", 
+	   GTS_COLORED_VERTEX (o)->c.r, 
+	   GTS_COLORED_VERTEX (o)->c.g, 
+	   GTS_COLORED_VERTEX (o)->c.b);
+}
+
+static GtsColor gts_colored_vertex_color (GtsObject * o)
+{
+  return GTS_COLORED_VERTEX (o)->c;
+}
+
+static void gts_colored_vertex_class_init (GtsVertexClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gts_colored_vertex_read;
+  GTS_OBJECT_CLASS (klass)->write = gts_colored_vertex_write;
+  GTS_OBJECT_CLASS (klass)->color = gts_colored_vertex_color;
+}
+
+static void gts_colored_vertex_init (GtsColoredVertex * object)
+{
+  object->c.r = object->c.g = object->c.b = 1.;
+}
+
+GtsVertexClass * gts_colored_vertex_class (void)
+{
+  static GtsVertexClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gts_colored_vertex_info = {
+      "GtsColoredVertex",
+      sizeof (GtsColoredVertex),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) gts_colored_vertex_class_init,
+      (GtsObjectInitFunc) gts_colored_vertex_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_vertex_class ()),
+				  &gts_colored_vertex_info);
+  }
+
+  return klass;
+}
+
+/* GfsVertex: Header */
+
+typedef struct _GfsVertex         GfsVertex;
+
+struct _GfsVertex {
+  /*< private >*/
+  GtsColoredVertex parent;
+
+  /*< public >*/
+  gdouble v;
+};
+
+#define GFS_VERTEX(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsVertex,\
+					         gfs_vertex_class ())
+#define GFS_IS_VERTEX(obj)         (gts_object_is_from_class (obj,\
+						 gfs_vertex_class ()))
+
+GtsPointClass * gfs_vertex_class  (void);
+
+/* GfsVertex: Object */
+
+static void gfs_vertex_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (v)");
+    return;
+  }
+  GFS_VERTEX (*o)->v = atof (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void gfs_vertex_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gts_colored_vertex_class ())->parent_class->write)
+      (o, fp);
+  fprintf (fp, " %g", GFS_VERTEX (o)->v);
+}
+
+static void gfs_vertex_class_init (GtsPointClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_vertex_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_vertex_write;
+}
+
+GtsPointClass * gfs_vertex_class (void)
+{
+  static GtsPointClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_vertex_info = {
+      "GfsVertex",
+      sizeof (GfsVertex),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) gfs_vertex_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gts_colored_vertex_class ()),
+			    &gfs_vertex_info);
+  }
+
+  return klass;
+}
+
+/* GfsTwistedVertex: Header */
+
+typedef struct _GfsTwistedVertex         GfsTwistedVertex;
+
+struct _GfsTwistedVertex {
+  /*< private >*/
+  GfsVertex parent;
+
+  /*< public >*/
+  gdouble theta;
+};
+
+#define GFS_TWISTED_VERTEX(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsTwistedVertex,\
+					         gfs_twisted_vertex_class ())
+#define GFS_IS_TWISTED_VERTEX(obj)         (gts_object_is_from_class (obj,\
+						 gfs_twisted_vertex_class ()))
+
+GtsPointClass * gfs_twisted_vertex_class  (void);
+
+/* GfsTwistedVertex: Object */
+
+static void gfs_twisted_vertex_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_twisted_vertex_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_twisted_vertex_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (theta)");
+    return;
+  }
+  GFS_TWISTED_VERTEX (*o)->theta = atof (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void gfs_twisted_vertex_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_twisted_vertex_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_twisted_vertex_class ())->parent_class->write)
+      (o, fp);
+  fprintf (fp, " %g", GFS_TWISTED_VERTEX (o)->theta);
+}
+
+static void gfs_twisted_vertex_class_init (GtsPointClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_twisted_vertex_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_twisted_vertex_write;
+}
+
+GtsPointClass * gfs_twisted_vertex_class (void)
+{
+  static GtsPointClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_twisted_vertex_info = {
+      "GfsTwistedVertex",
+      sizeof (GfsTwistedVertex),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) gfs_twisted_vertex_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gfs_vertex_class ()),
+			    &gfs_twisted_vertex_info);
+  }
+
+  return klass;
+}
+
+static void matrix_transpose (GtsMatrix * m)
+{
+  guint i, j;
+
+  for (i = 1; i < 3; i++)
+    for (j = 0; j < i; j++) {
+      gdouble t = m[i][j];
+
+      m[i][j] = m[j][i];
+      m[j][i] = t;
+    }
+}
+
+static void base (GtsMatrix * b, GtsPoint * p1, GtsPoint * p2)
+{
+  GtsVector x, y;
+
+  x[0] = b[0][0];
+  x[1] = b[1][0];
+  x[2] = b[2][0];
+  gts_vector_init (b[2], p2, p1);
+  gts_vector_normalize (b[2]);
+  gts_vector_cross (y, b[2], x);
+  if (gts_vector_norm (y) > 1e-2) {
+    b[1][0] = y[0];
+    b[1][1] = y[1];
+    b[1][2] = y[2];
+    gts_vector_normalize (b[1]);
+  }
+  gts_vector_cross (b[0], b[1], b[2]);
+  gts_vector_normalize (b[0]);
+  matrix_transpose (b);
+}
+
+static void edge_list (GtsMatrix * b, GtsPoint * o,
+		       GSList * profile,
+		       GtsSurface * s,
+		       GtsEdge ** e, guint ne)
+{
+  guint i;
+  GtsVertex * vold = NULL;
+  GtsVertex * vfirst = NULL;
+  gboolean colored = FALSE;
+  GtsMatrix * c;
+
+  if (GTS_IS_COLORED_VERTEX (o) && 
+      gts_object_class_is_from_class (GTS_OBJECT_CLASS (s->vertex_class),
+				      GTS_OBJECT_CLASS (gts_colored_vertex_class ())))
+    colored = TRUE;
+  if (GFS_IS_TWISTED_VERTEX (o)) {
+    gdouble t = GFS_TWISTED_VERTEX (o)->theta;
+    gdouble sint = sin (t), cost = cos (t);
+    GtsMatrix * r = gts_matrix_new (cost, -sint, 0., 0.,
+				    sint,  cost, 0., 0.,
+				    0.,      0., 1., 0.,
+				    0.,      0., 0., 0.);
+    
+    c = gts_matrix_product (b, r);
+    gts_matrix_destroy (r);
+  }
+  else
+    c = gts_matrix_new (b[0][0], b[0][1], b[0][2], 0.,
+			b[1][0], b[1][1], b[1][2], 0.,
+			b[2][0], b[2][1], b[2][2], 0.,
+			0., 0., 0., 0.);
+
+  for (i = 0; i <= ne && profile; i++, profile = profile->next) {
+    GtsPoint * p = profile->data;
+    GtsVertex * v = gts_vertex_new (s->vertex_class, p->x, p->y, 0.);
+
+    if (colored)
+      GTS_COLORED_VERTEX (v)->c = GTS_COLORED_VERTEX (o)->c;
+    
+    gts_point_transform (GTS_POINT (v), c);
+    GTS_POINT (v)->x += o->x;
+    GTS_POINT (v)->y += o->y;
+    GTS_POINT (v)->z += o->z;
+
+    if (vold != NULL)
+      e[i-1] = gts_edge_new (s->edge_class, vold, v);
+    vold = v;
+    if (!vfirst) vfirst = v;
+  }
+  if (i <= ne && vold)
+    e[i-1] = gts_edge_new (s->edge_class, vold, vfirst);
+  gts_matrix_destroy (c);
+}
+
+static void add_face (GtsSurface * s, GtsEdge ** e1, GtsEdge ** e2,
+		      guint ne)
+{
+  guint i;
+
+  for (i = 0; i < ne; i++) {
+    GtsVertex * v1 = GTS_SEGMENT (e1[i])->v1;
+    GtsVertex * v2 = GTS_SEGMENT (e2[i])->v1;
+    GtsVertex * v3 = GTS_SEGMENT (e2[i])->v2;
+    GtsVertex * v4 = GTS_SEGMENT (e1[i])->v2;
+    GtsEdge * e3 = gts_edge_new (s->edge_class, v1, v3);
+    GtsEdge * e4 = GTS_EDGE (gts_vertices_are_connected (v1, v2));
+    GtsEdge * e5 = GTS_EDGE (gts_vertices_are_connected (v3, v4));
+
+    if (e4 == NULL)
+      e4 = gts_edge_new (s->edge_class, v1, v2);
+    if (e5 == NULL)
+      e5 = gts_edge_new (s->edge_class, v3, v4);
+
+    gts_surface_add_face (s, gts_face_new (s->face_class, e4, e2[i], e3));
+    gts_surface_add_face (s, gts_face_new (s->face_class, e3, e5, e1[i]));
+  }
+}
+
+static GList * next_far_enough (GList * p, gdouble size)
+{
+  GtsPoint * ps;
+  GList * pf = NULL;
+
+  if (p == NULL)
+    return NULL;
+  ps = p->data;
+  p = p->next;
+  size *= size;
+  while (p && !pf) {
+    if (gts_point_distance2 (ps, p->data) > size)
+      pf = p;
+    p = p->next;
+  }
+  return pf;
+}
+
+void gfs_extrude_profile (GtsSurface * s,
+			  GSList * profile,
+			  gboolean closed,
+			  GList * path)
+{
+  GtsMatrix * r;
+  GtsPoint * p0, * p1, * p2;
+  GtsEdge ** e1, ** e2, ** tmp;
+  GtsBBox * bb;
+  gdouble size;
+  guint ne;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (profile != NULL);
+  g_return_if_fail (path != NULL);
+
+  bb = gts_bbox_points (gts_bbox_class (), profile);
+  size = bb->x2 - bb->x1;
+  if (bb->y2 - bb->y1 > size)
+    size = bb->y2 - bb->y1;
+  gts_object_destroy (GTS_OBJECT (bb));
+
+  size /= 4.;
+
+  p0 = path->data;
+  path = next_far_enough (path, size);
+  if (path == NULL)
+    return;
+  p1 = path->data;
+  r = gts_matrix_identity (NULL);
+  ne = closed ? g_slist_length (profile) : g_slist_length (profile) - 1;
+  e1 = g_malloc (sizeof (GtsEdge *)*ne);
+  e2 = g_malloc (sizeof (GtsEdge *)*ne);
+
+  base (r, p0, p1);
+  edge_list (r, p0, profile, s, e1, ne);
+  do {
+    path = next_far_enough (path, size);
+    p2 = path ? path->data : NULL;
+    if (p2)
+      base (r, p0, p2);
+    else
+      base (r, p0, p1);
+    edge_list (r, p1, profile, s, e2, ne);
+    add_face (s, e1, e2, ne);
+    tmp = e1;
+    e1 = e2;
+    e2 = tmp;
+    p0 = p1;
+    p1 = p2;
+  } while (p1);
+
+  g_free (e1);
+  g_free (e2);
+  gts_matrix_destroy (r);
+}
+
+static gdouble triangle_area (FttVector p1, FttVector p2, FttVector p3)
+{
+  GtsVector v1, v2, a;
+
+  v1[0] = p2.x - p1.x; v1[1] = p2.y - p1.y; v1[2] = p2.z - p1.z;
+  v2[0] = p3.x - p2.x; v2[1] = p3.y - p2.y; v2[2] = p3.z - p2.z;
+  gts_vector_cross (a, v1, v2);
+  return gts_vector_norm (a)/2.;
+}
+
+static gdouble circumcircle_radius (FttVector p1, FttVector p2, FttVector p3)
+{
+  gdouble area = triangle_area (p1, p2, p3);
+
+  if (area == 0.)
+    return G_MAXDOUBLE;
+  else {
+    GtsVector a, b, c;
+    gts_vector_init (a, &p1, &p2);
+    gts_vector_init (b, &p2, &p3);
+    gts_vector_init (c, &p3, &p1);
+    return gts_vector_norm (a)*gts_vector_norm (b)*gts_vector_norm (c)/area;
+  }
+}
+
+static GSList * circle_profile (GtsPointClass * klass, 
+				gdouble radius, guint np)
+{
+  GSList * lp = NULL;
+  guint i;
+
+  for (i = 0; i < np; i++) {
+    gdouble a = 2.*M_PI*i/(gdouble) np;
+
+    lp = g_slist_prepend (lp, gts_point_new (klass, radius*cos (a), radius*sin(a), 0.));
+  }
+  return lp;
+}
+
+static GSList * ribbon_profile (GtsPointClass * klass, 
+				gdouble half_width)
+{
+  GSList * lp = NULL;
+
+  lp = g_slist_prepend (lp, gts_point_new (klass, 0., -half_width, 0.));
+  lp = g_slist_prepend (lp, gts_point_new (klass, 0., half_width, 0.));
+  return lp;
+}
+
+#if (!FTT_2D)
+static void vorticity_vector (FttCell * cell, gpointer * data)
+{
+  gdouble size = ftt_cell_size (cell);
+  GfsVariable ** g = data[0];
+  GfsVariable ** v = data[1];
+
+  GFS_VARIABLE (cell, g[0]->i) = (gfs_center_gradient (cell, FTT_Y, v[2]->i) -
+				  gfs_center_gradient (cell, FTT_Z, v[1]->i))/size;
+  GFS_VARIABLE (cell, g[1]->i) = (gfs_center_gradient (cell, FTT_Z, v[0]->i) -
+				  gfs_center_gradient (cell, FTT_X, v[2]->i))/size;
+  GFS_VARIABLE (cell, g[2]->i) = (gfs_center_gradient (cell, FTT_X, v[1]->i) -
+				  gfs_center_gradient (cell, FTT_Y, v[0]->i))/size;
+}
+#endif /* 3D */
+
+static gdouble interpolated_velocity (FttCell * cell, FttVector p, GfsVariable ** U,
+				      gdouble direction,
+				      FttVector * u)
+{
+  FttComponent c;
+  gdouble nu = 0.;
+  gdouble (* interpolate) (FttCell *, FttVector, GfsVariable * v) = GFS_IS_MIXED (cell) ?
+    gfs_mixed_cell_interpolate : gfs_interpolate;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    (&u->x)[c] = direction* (*interpolate) (cell, p, U[c]);
+    nu += (&u->x)[c]*(&u->x)[c];
+  }
+  return nu;
+}
+
+static GList * grow_curve (GfsDomain * domain,
+			   GfsVariable ** U,
+			   FttVector p,
+			   GfsVariable * var,
+			   gdouble min, 
+			   gdouble max,
+			   gboolean twist,
+			   GList * path,
+			   gdouble direction,
+			   gboolean (* stop) (FttCell *, GList *, gpointer),
+			   gpointer data)
+{
+  FttCell * cell;
+  gdouble delta = 0.2;
+  GtsPoint * oldp = NULL;
+  FttVector p1, p2;
+  gdouble cost = 0., theta = 0.;
+  gdouble maxcost = 4e-9;
+  guint nstep = 0, nmax = 10000;
+  GtsPointClass * path_class = gfs_vertex_class ();
+  Colormap * colormap = NULL;
+
+  if (min < max)
+    colormap = colormap_jet ();
+
+#if (!FTT_2D)
+  GfsVariable * vort[FTT_DIMENSION];
+  if (twist) {
+    FttComponent c;
+    gpointer data[2];
+
+    path_class = GTS_POINT_CLASS (gfs_twisted_vertex_class ());
+    for (c = 0; c < FTT_DIMENSION; c++)
+      vort[c] = gfs_temporary_variable (domain);
+    gfs_variable_set_vector (vort, FTT_DIMENSION);
+    data[0] = vort;
+    data[1] = U;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) vorticity_vector, data);
+    for (c = 0; c < FTT_DIMENSION; c++)
+      gfs_domain_cell_traverse (domain,
+				FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				(FttCellTraverseFunc) vort[c]->fine_coarse, vort[c]);
+  }
+#else /* 2D */
+  twist = FALSE;
+#endif /* 2D */  
+
+  p1 = p2 = p;
+  while ((cell = gfs_domain_locate (domain, p, -1, NULL)) != NULL &&
+	 circumcircle_radius (p1, p2, p) > ftt_cell_size (cell) &&
+	 nmax--) {
+    gdouble h = delta*ftt_cell_size (cell);
+    FttVector u;
+    FttComponent c;
+    gdouble nu = 0.;
+
+    cost += triangle_area (p1, p2, p);
+    p1 = p2;
+    p2 = p;
+    if (oldp == NULL || cost > maxcost) {
+      oldp = gts_point_new (path_class, p.x, p.y, p.z);
+      if (var)
+	GFS_VERTEX (oldp)->v = gfs_interpolate (cell, p, var);
+      if (colormap)
+	GTS_COLORED_VERTEX (oldp)->c = 
+	  colormap_color (colormap, (GFS_VERTEX (oldp)->v - min)/(max - min));
+      if (twist)
+	GFS_TWISTED_VERTEX (oldp)->theta = theta;
+      path = g_list_prepend (path, oldp);
+      if (stop != NULL && (* stop) (cell, path, data))
+	break;
+      cost = 0.;
+      nstep = 0;
+    }
+
+    nu = interpolated_velocity (cell, p, U, direction, &u);
+    if (nu > 0) {
+      FttVector p1 = p;
+      FttCell * cell1;
+
+      nu = 2.*sqrt (nu);
+      for (c = 0; c < FTT_DIMENSION; c++)
+	(&p1.x)[c] += h*(&u.x)[c]/nu;
+      cell1 = gfs_domain_locate (domain, p1, -1, NULL);
+      if (!cell1)
+	break;
+      nu = interpolated_velocity (cell1, p1, U, direction, &u);
+    }
+    else
+      break;
+    if (nu > 0. && nstep++ < nmax) {
+      FttVector p1;
+
+      p1 = p;
+      nu = sqrt (nu);
+      for (c = 0; c < FTT_DIMENSION; c++)
+	((gdouble *) &p)[c] += h*((gdouble *) &u)[c]/nu;
+#if (!FTT_2D)
+      if (twist) {
+	GtsVector rot;
+	GtsVector dx;
+
+	dx[0] = p1.x - p.x; dx[1] = p1.y - p.y; dx[2] = p1.z - p.z;
+	for (c = 0; c < FTT_DIMENSION; c++)
+	  rot[c] = gfs_interpolate (cell, p1, vort[c]);
+	theta += gts_vector_scalar (rot, dx)/nu;
+      }
+#endif /* 3D */
+    }
+    else
+      break;
+  }
+  if (oldp && (p2.x != oldp->x || p2.y != oldp->y || p2.z != oldp->z)) {
+    cell = gfs_domain_locate (domain, p2, -1, NULL);
+    if (cell) {
+      oldp = gts_point_new (path_class, p2.x, p2.y, p2.z);
+      if (var)
+	GFS_VERTEX (oldp)->v = gfs_interpolate (cell, p2, var);
+      if (twist)
+	GFS_TWISTED_VERTEX (oldp)->theta = theta;
+      path = g_list_prepend (path, oldp);
+    }
+  }
+
+  if (colormap)
+    colormap_destroy (colormap);
+
+#if (!FTT_2D)
+  if (twist) {
+    FttComponent c;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      gts_object_destroy (GTS_OBJECT (vort[c]));
+  }
+#endif /* 3D */
+  return direction > 0. ? g_list_reverse (path) : path;
+}
+
+GList * gfs_streamline_new (GfsDomain * domain,
+			    GfsVariable ** U,
+			    FttVector p,
+			    GfsVariable * var,
+			    gdouble min,
+			    gdouble max,
+			    gboolean twist,
+			    gboolean (* stop) (FttCell *, 
+					       GList *,
+					       gpointer),
+			    gpointer data)
+{
+  GList * i, * path;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (U != NULL, NULL);
+
+  i = grow_curve (domain, U, p, var, min, max, twist, NULL, 1., stop, data);
+  path = g_list_remove_link (i, i);
+  if (i != NULL)
+    gts_object_destroy (i->data);
+  g_list_free_1 (i);
+  path = grow_curve (domain, U, p, var, min, max, twist, path, -1., stop, data);
+  return path;
+}
+
+void gfs_streamline_write (GList * stream, FILE * fp)
+{
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "GfsStreamline %u\n", g_list_length (stream));
+  while (stream) {
+    (* GTS_OBJECT (stream->data)->klass->write) (stream->data, fp);
+    fputc ('\n', fp);
+    stream = stream->next;
+  }
+}
+
+GList * gfs_streamline_read (GtsFile * fp)
+{
+  GList * stream = NULL;
+  guint n = 0, nv;
+
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsStreamline)");
+    return NULL;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (number of vertices)");
+    return NULL;
+  }
+  nv = atoi (fp->token->str);
+  gts_file_first_token_after (fp, '\n');
+  while (fp->type != GTS_ERROR && n < nv) {
+    GtsObject * o = 
+      gts_object_new (GTS_OBJECT_CLASS (gfs_twisted_vertex_class ()));
+
+    (*o->klass->read) (&o, fp);
+    gts_file_first_token_after (fp, '\n');
+    stream = g_list_prepend (stream, o);
+    n++;
+  }
+
+  if (fp->type == GTS_ERROR) {
+    g_list_free (stream);
+    return NULL;
+  }
+
+  return stream;
+}
+
+void gfs_streamline_draw (GList * stream, FILE * fp)
+{
+  guint n = g_list_length (stream);
+
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "VECT 1 %u 0 %u 0\n", n, n);
+  while (stream) {
+    fprintf (fp, "%g %g %g\n",
+	     GTS_POINT (stream->data)->x,
+	     GTS_POINT (stream->data)->y,
+	     GTS_POINT (stream->data)->z);
+    stream = stream->next;
+  }
+}
+
+void gfs_streamline_destroy (GList * stream)
+{
+  g_list_foreach (stream, (GFunc) gts_object_destroy, NULL);
+  g_list_free (stream);
+}
+
+void gfs_draw_stream_cylinder (GfsDomain * domain,
+			       FttVector p,
+			       gdouble radius,
+			       GfsVariable * var,
+			       gdouble min, gdouble max,
+			       FILE * fp)
+{
+  GSList * profile;
+  GList * path;
+  GtsSurface * s;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  s = gts_surface_new (gts_surface_class (),
+		       gts_face_class (),
+		       gts_edge_class (),
+		       min < max ? gts_colored_vertex_class () :
+		       gts_vertex_class ());
+  path = gfs_streamline_new (domain, gfs_domain_velocity (domain), p, var, min, max, FALSE, 
+			     NULL, NULL);
+  profile = circle_profile (gts_point_class (), radius, 10);
+  gfs_extrude_profile (s, profile, TRUE, path);
+  gts_surface_write_oogl (s, fp);
+  gts_object_destroy (GTS_OBJECT (s));
+  gfs_streamline_destroy (path);
+  g_slist_foreach (profile, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (profile);
+}
+
+void gfs_draw_stream_ribbon (GfsDomain * domain,
+			     FttVector p,
+			     gdouble half_width,
+			     GfsVariable * var,
+			     gdouble min, gdouble max,
+			     FILE * fp)
+{
+  GList * path;
+  GSList * profile;
+  GtsSurface * s;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  s = gts_surface_new (gts_surface_class (),
+		       gts_face_class (),
+		       gts_edge_class (),
+		       min < max ? gts_colored_vertex_class () :
+		       gts_vertex_class ());
+  path = gfs_streamline_new (domain, gfs_domain_velocity (domain), p, var, min, max, TRUE, 
+			     NULL, NULL);
+  profile = ribbon_profile (gts_point_class (), half_width);
+  gfs_extrude_profile (s, profile, FALSE, path);
+  gts_surface_write_oogl (s, fp);
+  gts_object_destroy (GTS_OBJECT (s));
+  gfs_streamline_destroy (path);
+  g_slist_foreach (profile, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (profile);
+}
+
+void gfs_draw_streamline (GfsDomain * domain,
+			  FttVector p,
+			  FILE * fp)
+{
+  GList * path;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  path = gfs_streamline_new (domain, gfs_domain_velocity (domain), p, NULL, 0., 0., FALSE, 
+			     NULL, NULL);
+  gfs_streamline_draw (path, fp);
+  gfs_streamline_destroy (path);
+}
+
+#if !FTT_2D
+
+static gdouble point_orientation (FttVector p[3], FttVector * c)
+{
+  gdouble adx, bdx, cdx;
+  gdouble ady, bdy, cdy;
+  gdouble adz, bdz, cdz;
+  
+  adx = p[0].x - c->x;
+  bdx = p[1].x - c->x;
+  cdx = p[2].x - c->x;
+  ady = p[0].y - c->y;
+  bdy = p[1].y - c->y;
+  cdy = p[2].y - c->y;
+  adz = p[0].z - c->z;
+  bdz = p[1].z - c->z;
+  cdz = p[2].z - c->z;
+  
+  return (adx * (bdy * cdz - bdz * cdy) +
+	  bdx * (cdy * adz - cdz * ady) +
+	  cdx * (ady * bdz - adz * bdy));
+}
+
+/**
+ * gfs_plane_cuts_cell:
+ * @plane: three points belonging to the plane.
+ * @cell: a #FttCell.
+ *
+ * Returns: %TRUE if @plane cuts @cell, %FALSE otherwise.
+ */
+gboolean gfs_plane_cuts_cell (FttVector plane[3], FttCell * cell)
+{
+  FttVector o;
+  gdouble h = ftt_cell_size (cell)*SLIGHTLY_LARGER;
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+
+  ftt_cell_pos (cell, &o);
+  o.x -= h/2.; o.y -= h/2.; o.z -= h/2.;
+  for (i = 0; i < 12; i++) {
+    FttVector e, d;
+    gdouble a, b;
+    d.x = o.x + h*edge[i][0].x; d.y = o.y + h*edge[i][0].y; d.z = o.z + h*edge[i][0].z;
+    e.x = o.x + h*edge[i][1].x; e.y = o.y + h*edge[i][1].y; e.z = o.z + h*edge[i][1].z;
+    a = point_orientation (plane, &e);
+    b = point_orientation (plane, &d);
+    if ((a <= 0. && b > 0.) || (a >= 0. && b < 0.))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+static void cube_plane_intersection (FttCell * cell,
+				     FttVector * O,
+				     FttVector * n,
+				     FttVector p[12],
+				     gint orient[12],
+				     GfsVariable * var,
+				     gdouble v[12],
+				     gint max_level)
+{
+  FttVector o;
+  gdouble h = ftt_cell_size (cell)*SLIGHTLY_LARGER, vc[8];
+  guint i;
+
+  if (var)
+    for (i = 0; i < 8; i++)
+      vc[i] = G_MAXDOUBLE;
+
+  ftt_cell_pos (cell, &o);
+  o.x -= h/2.; o.y -= h/2.; o.z -= h/2.;
+  for (i = 0; i < 12; i++) {
+    FttVector e, d;
+    d.x = o.x + h*edge[i][0].x; d.y = o.y + h*edge[i][0].y; d.z = o.z + h*edge[i][0].z;
+    e.x = o.x + h*edge[i][1].x; e.y = o.y + h*edge[i][1].y; e.z = o.z + h*edge[i][1].z;
+    gdouble den = n->x*(e.x - d.x) + n->y*(e.y - d.y) + n->z*(e.z - d.z);
+    orient[i] = -1;
+    if (fabs (den) > 1e-10) {
+      gdouble t = (n->x*(O->x - d.x) + n->y*(O->y - d.y) + n->z*(O->z - d.z))/den;
+      if (t >= 0. && t < 1.) {
+	p[i].x = d.x + t*(e.x - d.x); p[i].y = d.y + t*(e.y - d.y); p[i].z = d.z + t*(e.z - d.z);
+	orient[i] = (n->x*(e.x - O->x) + n->y*(e.y - O->y) + n->z*(e.z - O->z) > 0.);
+	if (var) {
+	  guint j = edge1[i][0];
+	  if (vc[j] == G_MAXDOUBLE)
+	    vc[j] = gfs_cell_corner_value (cell, corner[j], var, max_level);
+	  d.z = vc[j];
+	  j = edge1[i][1];
+	  if (vc[j] == G_MAXDOUBLE)
+	    vc[j] = gfs_cell_corner_value (cell, corner[j], var, max_level);
+	  e.z = vc[j];
+	  v[i] = d.z + t*(e.z - d.z);
+	}
+      }
+    }
+  }
+}
+
+/**
+ * gfs_cut_cube_vertices:
+ * @cell: a #FttCell.
+ * @maxlevel: the maximum level to consider (or -1).
+ * @p: a point on the plane.
+ * @n: the normal to the plane.
+ * @v: where to return the vertices coordinates.
+ * @d: where to return the direction.
+ * @var: a #GfsVariable or %NULL.
+ * @val: where to return the values of @var or %NULL.
+ *
+ * Fills @v, @d and @val with the coordinates/values of the vertices,
+ * intersections of @cell with the plane defined by @p and @n.
+ *
+ * The vertices are ordered consistently to define a consistent,
+ * oriented polygon.
+ *
+ * Returns: the number of vertices (0 if the plane does not cut the cell).
+ */
+guint gfs_cut_cube_vertices (FttCell * cell, gint maxlevel,
+			     FttVector * p, FttVector * n,
+			     FttVector v[12], FttDirection d[12],
+			     GfsVariable * var,
+			     gdouble val[12])
+{
+  FttVector a[12];
+  gdouble vv[12];
+  gint orient[12];
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, 0);
+  g_return_val_if_fail (p != NULL, 0);
+  g_return_val_if_fail (n != NULL, 0);
+  g_return_val_if_fail ((var == NULL && val == NULL) || (var != NULL && val != NULL), 0);
+
+  cube_plane_intersection (cell, p, n, a, orient, var, vv, maxlevel);
+  for (i = 0; i < 12; i++) {
+    guint nv = 0, e = i;
+    while (orient[e] >= 0) {
+      guint m = 0, * ne = connect[e][orient[e]];
+      d[nv] = ne[3];
+      if (var)
+	val[nv] = vv[e];
+      v[nv++] = a[e];
+      orient[e] = -1;
+      while (m < 3 && orient[e] < 0)
+	e = ne[m++];
+    }
+    if (nv > 2)
+      return nv;
+  }
+  return 0;
+}
+
+#endif /* 3D */
diff --git a/src/graphic.h b/src/graphic.h
new file mode 100644
index 0000000..c7b7cca
--- /dev/null
+++ b/src/graphic.h
@@ -0,0 +1,139 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GRAPHIC_H__
+#define __GRAPHIC_H__
+
+#include "domain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void               gfs_write_gts               (GfsDomain * domain, 
+						GfsVariable * v, 
+						FttTraverseFlags flags,
+						gint level,
+						GtsBBox * box,
+						FILE * fp);
+GtsSurface *       gfs_isosurface              (GfsDomain * domain, 
+						GfsVariable * v, 
+						gdouble val,
+						gint level);
+void               gfs_write_gnuplot           (GfsDomain * domain, 
+						GfsVariable * v, 
+						FttTraverseFlags flags,
+						gint level,
+						GtsBBox * bbox,
+						FILE * fp);
+void               gfs_write_ppm               (GfsDomain * domain, 
+						GtsBBox * box,
+						GfsVariable * v, 
+						gdouble min, 
+						gdouble max,
+						FttTraverseFlags flags,
+						gint level,
+						FILE * fp);
+gint               gfs_combine_ppm             (gchar ** fname, 
+						guint nname, 
+						FILE * fp);
+void               gfs_write_squares           (GfsDomain * domain, 
+						GfsVariable * v, 
+						gdouble min, 
+						gdouble max,
+						FttTraverseFlags flags,
+						gint level,
+						GtsBBox * bbox,
+						FILE * fp);
+void               gfs_write_mac_velocity      (GfsDomain * domain,
+						gdouble scale,
+						FttTraverseFlags flags,
+						gint level,
+						GtsBBox * bbox,
+						FILE * fp);
+void               gfs_draw_cells              (FttCell * cell,
+						FttTraverseFlags flags,
+						gint level,
+					       FILE * fp);
+void               gfs_draw_boundary_conditions (GfsDomain * domain, 
+						 FILE * fp);
+void               gfs_draw_solid_boundaries   (GfsDomain * domain, 
+						FILE * fp);
+void               gfs_draw_refined_boundaries (GfsDomain * domain, 
+						FILE * fp);
+void               gfs_draw_levels             (FttCell * cell, 
+						FILE * fp);
+void               gfs_draw_surface            (GfsDomain * domain,
+						GtsSurface * s,
+						GfsVariable * v, 
+						gdouble min, 
+						gdouble max,
+						FILE * fp);
+void               gfs_extrude_profile         (GtsSurface * s,
+						GSList * profile,
+						gboolean closed,
+						GList * path);
+GList *            gfs_streamline_new          (GfsDomain * domain,
+						GfsVariable ** U,
+						FttVector p,
+						GfsVariable * var,
+						gdouble min,
+						gdouble max,
+						gboolean twist,
+						gboolean (* stop) (FttCell *, 
+								   GList *, 
+								   gpointer),
+						gpointer data);
+void               gfs_streamline_write        (GList * stream, 
+						FILE * fp);
+GList *            gfs_streamline_read         (GtsFile * fp);
+void               gfs_streamline_draw         (GList * stream, 
+						FILE * fp);
+void               gfs_streamline_destroy      (GList * stream);
+void               gfs_draw_stream_cylinder    (GfsDomain * domain,
+						FttVector p, 
+						gdouble radius,
+						GfsVariable * var, 
+						gdouble min, 
+						gdouble max,
+						FILE * fp);
+void               gfs_draw_stream_ribbon      (GfsDomain * domain,
+						FttVector p, 
+						gdouble radius,
+						GfsVariable * var, 
+						gdouble min, 
+						gdouble max,
+						FILE * fp);
+void               gfs_draw_streamline         (GfsDomain * domain,
+						FttVector p,
+						FILE * fp);
+gboolean           gfs_plane_cuts_cell         (FttVector plane[3], 
+						FttCell * cell);
+guint              gfs_cut_cube_vertices       (FttCell * cell, 
+						gint maxlevel,
+						FttVector * p, FttVector * n,
+						FttVector v[12], FttDirection d[12],
+						GfsVariable * var,
+						gdouble val[12]);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GRAPHIC_H__ */
diff --git a/src/init.c b/src/init.c
new file mode 100644
index 0000000..79b6dbc
--- /dev/null
+++ b/src/init.c
@@ -0,0 +1,314 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#ifdef HAVE_FENV_H
+# define _GNU_SOURCE
+# include <fenv.h>
+#endif /* HAVE_FENV_H */
+
+#include <stdlib.h>
+#include <locale.h>
+
+#include "boundary.h"
+#include "mpi_boundary.h"
+#include "init.h"
+#include "refine.h"
+#include "output.h"
+#include "adaptive.h"
+#include "source.h"
+#include "tension.h"
+#include "ocean.h"
+#include "wave.h"
+#include "levelset.h"
+#include "vof.h"
+#include "solid.h"
+#include "moving.h"
+#include "river.h"
+#include "balance.h"
+#include "map.h"
+#include "metric.h"
+
+#include "modules.h"
+
+#ifdef HAVE_MPI
+# include <mpi.h>
+#endif /* HAVE_MPI */
+
+static void gfs_log (const gchar * log_domain,
+		     GLogLevelFlags log_level,
+		     const gchar * message)
+{
+  int type = 0;
+  gchar * pe;
+  const gchar stype[][10] = {
+    "ERROR", "CRITICAL", "WARNING", "MESSAGE", "INFO", "DEBUG"
+  };
+
+#ifdef HAVE_MPI
+  int rank = -1;
+  MPI_Comm_size (MPI_COMM_WORLD, &rank);
+  if (rank > 1)
+    MPI_Comm_rank (MPI_COMM_WORLD, &rank);
+  else
+    rank = -1;
+  if (rank >= 0) {
+    char name[MPI_MAX_PROCESSOR_NAME];
+    int length;
+    MPI_Get_processor_name (name, &length);
+    pe = g_strdup_printf ("PE %d (%s): ", rank, name);
+  }
+  else
+#endif /* HAVE_MPI */
+    pe = g_strdup ("");
+
+  switch (log_level & G_LOG_LEVEL_MASK) {
+  case G_LOG_LEVEL_ERROR:    type = 0; break;
+  case G_LOG_LEVEL_CRITICAL: type = 1; break;
+  case G_LOG_LEVEL_WARNING:  type = 2; break;
+  case G_LOG_LEVEL_MESSAGE:  type = 3; break;
+  case G_LOG_LEVEL_INFO:     type = 4; break;
+  case G_LOG_LEVEL_DEBUG:    type = 5; break;
+  default:
+    g_assert_not_reached ();
+  }
+  fprintf (stderr, "\n%s-%s **: %s%s\n\n", 
+	   log_domain, stype[type], pe, message);
+  g_free (pe);
+}
+
+/**
+ * gfs_classes:
+ *
+ * Returns: a pointer to a NULL-terminated array of all the classes
+ * usable in Gerris parameter files.
+ */
+GtsObjectClass ** gfs_classes (void)
+{
+  static GtsObjectClass ** classes = NULL;
+  if (classes == NULL) { gpointer klass[] = {
+
+  gfs_global_class (),
+  gfs_simulation_class (),
+    gfs_ocean_class (),
+    gfs_advection_class (),
+    gfs_poisson_class (),
+    gfs_simulation_moving_class (),
+    gfs_axi_class (),
+    gfs_wave_class (),
+    gfs_river_class (),
+
+  gfs_surface_bc_class (),
+
+  gfs_box_class (),
+
+  gfs_gedge_class (),
+
+  gfs_bc_dirichlet_class (),
+  gfs_bc_subcritical_class (),
+  gfs_bc_neumann_class (),
+  gfs_bc_navier_class (),
+  gfs_bc_flather_class (),
+
+  gfs_boundary_class (),
+    gfs_boundary_inflow_constant_class (),
+    gfs_boundary_outflow_class (),
+    gfs_boundary_gradient_class (),
+    gfs_boundary_periodic_class (),
+      gfs_boundary_mpi_class (),
+
+  gfs_refine_class (),
+    gfs_refine_solid_class (),
+    gfs_refine_surface_class (),
+      gfs_refine_distance_class (),
+      gfs_refine_height_class (),
+
+  gfs_event_class (),
+    gfs_variable_class (),
+      gfs_variable_tracer_class (),
+        gfs_variable_tracer_vof_class (),
+      gfs_variable_residual_class (),
+      gfs_variable_filtered_class (),
+      gfs_variable_diagonal_class (),
+      gfs_variable_function_class (),
+#if FTT_2D
+        gfs_variable_stream_function_class (),
+#endif /* FTT_2D */
+      gfs_variable_curvature_class (),
+        gfs_variable_position_class (),
+      gfs_variable_distance_class (),
+
+    gfs_solid_class (),
+      gfs_solid_moving_class(),
+
+    gfs_init_class (),
+    gfs_init_flow_constant_class (),
+    gfs_init_fraction_class (),
+#if FTT_2D
+    gfs_init_vorticity_class (),
+#endif /* FTT_2D */
+    gfs_init_wave_class (),
+
+    gfs_metric_lon_lat_class (),
+    gfs_metric_cubed_class (),
+
+    gfs_adapt_class (),
+      gfs_adapt_vorticity_class (),
+      gfs_adapt_streamline_curvature_class (),
+      gfs_adapt_function_class (),
+      gfs_adapt_gradient_class (),
+        gfs_adapt_error_class (),
+
+    gfs_event_sum_class (),
+      gfs_event_sum_direction_class (),
+    gfs_event_harmonic_class (),
+    gfs_event_stop_class (),
+    gfs_event_script_class (),
+    gfs_event_balance_class (),
+    gfs_source_generic_class (),
+      gfs_source_scalar_class (),
+        gfs_source_class (),
+          gfs_source_control_class (),
+            gfs_source_control_field_class (),
+          gfs_source_flux_class (),
+        gfs_source_diffusion_class (),
+          gfs_source_diffusion_explicit_class (),
+      gfs_source_velocity_class (),
+        gfs_source_viscosity_class (),
+          gfs_source_viscosity_explicit_class (),
+        gfs_source_friction_class (),
+        gfs_source_coriolis_class (),
+          gfs_source_tension_class (),
+          gfs_source_tension_css_class (),
+#if !FTT_2D
+        gfs_source_hydrostatic_class (),
+#endif /* 2D3 or 3D */
+    gfs_remove_droplets_class (),
+    gfs_remove_ponds_class (),
+    gfs_event_filter_class (),
+    gfs_event_list_class (),
+   
+    gfs_output_class (),
+      gfs_output_time_class (),
+      gfs_output_progress_class (),
+      gfs_output_projection_stats_class (),
+      gfs_output_diffusion_stats_class (),
+      gfs_output_solid_stats_class (),
+      gfs_output_adapt_stats_class (),
+      gfs_output_timing_class (),
+      gfs_output_balance_class (),
+      gfs_output_solid_force_class (),
+      gfs_output_location_class (),
+      gfs_output_simulation_class (),
+      gfs_output_boundaries_class (),
+      gfs_output_particle_class (),
+
+      gfs_output_scalar_class (),
+        gfs_output_scalar_norm_class (),
+        gfs_output_scalar_stats_class (),
+        gfs_output_scalar_sum_class (),
+        gfs_output_scalar_maxima_class (),
+        gfs_output_scalar_histogram_class (),
+        gfs_output_droplet_sums_class (),
+        gfs_output_error_norm_class (),
+          gfs_output_correlation_class (),
+	gfs_output_squares_class (),
+	gfs_output_streamline_class (),
+        gfs_output_ppm_class (),  
+
+  gfs_map_class (),
+    gfs_map_function_class (),
+  
+  NULL};
+
+    guint n = 0;
+    gpointer * c = klass;
+    while (*(c++)) n++;
+    classes = g_malloc ((n + 1)*sizeof (gpointer));
+    memcpy (classes, klass, (n + 1)*sizeof (gpointer));
+  }
+  return classes;
+}
+
+typedef void (* AtExitFunc) (void);
+
+/**
+ * gfs_init:
+ * @argc: a pointer on the number of command line arguments passed to
+ * the program.
+ * @argv: a pointer on the command line arguments passed to the
+ * program.
+ *
+ * Initializes the Gerris library. This function must be called before
+ * any other function of the library.
+ */
+void gfs_init (int * argc, char *** argv)
+{
+  static gboolean initialized = FALSE;
+
+  if (initialized)
+    return;
+
+  if (!setlocale (LC_ALL, "POSIX"))
+    g_warning ("cannot set locale to POSIX");
+
+#ifdef HAVE_MPI
+  MPI_Initialized (&initialized);
+  if (!initialized) {
+    if (!argc || !argv) {
+      int argc1 = 1;
+      char ** argv1;
+
+      argv1 = g_malloc (sizeof (char *));
+      argv1[0] = g_strdup ("gfs_init");
+      MPI_Init (&argc1, &argv1);
+      g_free (argv1[0]); g_free (argv1);
+    }
+    else
+      MPI_Init (argc, argv);
+    MPI_Errhandler_set (MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
+  }
+  atexit ((AtExitFunc) MPI_Finalize);
+#endif /* HAVE_MPI */
+  initialized = TRUE;
+
+#ifdef FE_NOMASK_ENV
+# ifdef FE_DIVBYZERO
+  feenableexcept (FE_DIVBYZERO);
+# endif /* FE_DIVBYZERO */
+#endif /* FE_NO_MASK_ENV */
+
+  g_log_set_handler (G_LOG_DOMAIN,
+		     G_LOG_LEVEL_ERROR |
+		     G_LOG_LEVEL_CRITICAL |
+		     G_LOG_LEVEL_WARNING |
+		     G_LOG_LEVEL_MESSAGE |
+		     G_LOG_LEVEL_INFO |
+		     G_LOG_LEVEL_DEBUG |
+		     G_LOG_FLAG_FATAL |
+		     G_LOG_FLAG_RECURSION,
+		     (GLogFunc) gfs_log, NULL);
+
+  /* Instantiates classes before reading any domain or simulation file */
+  gfs_classes ();
+
+  /* If modules are not supported, calls modules init functions */
+#include "modules.c"
+}
diff --git a/src/init.h b/src/init.h
new file mode 100644
index 0000000..425b2a2
--- /dev/null
+++ b/src/init.h
@@ -0,0 +1,37 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __INIT_H__
+#define __INIT_H__
+
+#include <gts.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+GtsObjectClass ** gfs_classes             (void);
+void              gfs_init                (int * argc, 
+					   char *** argv);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INIT_H__ */
diff --git a/src/isocube.h b/src/isocube.h
new file mode 100644
index 0000000..3abe95c
--- /dev/null
+++ b/src/isocube.h
@@ -0,0 +1,98 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2004 National Institute of Water and Atmospheric
+ * Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+/* isocube adapted from GTS (see gts/src/iso.c and gts/doc/isocube.fig) */
+static guint edge1[12][2] = {
+  {0, 4}, {1, 5}, {3, 7}, {2, 6},
+  {0, 2}, {1, 3}, {5, 7}, {4, 6},
+  {0, 1}, {4, 5}, {6, 7}, {2, 3}
+};
+static FttVector vertex[8] = {
+  {0.,0.,0.},{0.,0.,1.},{0.,1.,0.},{0.,1.,1.},
+  {1.,0.,0.},{1.,0.,1.},{1.,1.,0.},{1.,1.,1.}
+};
+static guint face[6][4][2] = {
+  {{7,0},{10,0},{6,1},{9,1}}, /* right */
+  {{4,0},{11,0},{5,1},{8,1}}, /* left */
+  {{3,0},{10,0},{2,1},{11,1}},/* top */
+  {{0,0},{9,0},{1,1},{8,1}},  /* bottom */
+  {{1,0},{6,0},{2,1},{5,1}},  /* front */
+  {{0,0},{7,0},{3,1},{4,1}}   /* back */
+};
+static guint face_v[6][4] = {
+  {4,6,7,5},/* right */
+  {0,2,3,1},/* left */
+  {2,6,7,3},/* top */
+  {0,4,5,1},/* bottom */
+  {1,5,7,3},/* front */
+  {0,4,6,2} /* back */
+};
+/* first index is the edge number, second index is the edge orientation 
+   (0 or 1), third index are the edges which this edge may connect to
+   in order and the corresponding face direction */
+static guint connect[12][2][4] = {
+  {{9, 1, 8, FTT_BOTTOM}, {4, 3, 7, FTT_BACK}},   /* 0 */
+  {{6, 2, 5, FTT_FRONT},  {8, 0, 9, FTT_BOTTOM}}, /* 1 */
+  {{10, 3, 11, FTT_TOP},  {5, 1, 6, FTT_FRONT}},  /* 2 */
+  {{7, 0, 4, FTT_BACK},   {11, 2, 10, FTT_TOP}},  /* 3 */
+  {{3, 7, 0, FTT_BACK},   {8, 5, 11, FTT_LEFT}},  /* 4 */
+  {{11, 4, 8, FTT_LEFT},  {1, 6, 2, FTT_FRONT}},  /* 5 */
+  {{2, 5, 1, FTT_FRONT},  {9, 7, 10, FTT_RIGHT}}, /* 6 */
+  {{10, 6, 9, FTT_RIGHT}, {0, 4, 3, FTT_BACK}},   /* 7 */
+  {{5, 11, 4, FTT_LEFT},  {0, 9, 1, FTT_BOTTOM}}, /* 8 */
+  {{1, 8, 0, FTT_BOTTOM}, {7, 10, 6, FTT_RIGHT}}, /* 9 */
+  {{6, 9, 7, FTT_RIGHT},  {3, 11, 2, FTT_TOP}},   /* 10 */
+  {{2, 10, 3, FTT_TOP},   {4, 8, 5, FTT_LEFT}}    /* 11 */
+};
+static FttVector edge[12][2] = {
+  {{0.,0.,0.},{1.,0.,0.}},{{0.,0.,1.},{1.,0.,1.}},{{0.,1.,1.},{1.,1.,1.}},{{0.,1.,0.},{1.,1.,0.}},
+  {{0.,0.,0.},{0.,1.,0.}},{{0.,0.,1.},{0.,1.,1.}},{{1.,0.,1.},{1.,1.,1.}},{{1.,0.,0.},{1.,1.,0.}},
+  {{0.,0.,0.},{0.,0.,1.}},{{1.,0.,0.},{1.,0.,1.}},{{1.,1.,0.},{1.,1.,1.}},{{0.,1.,0.},{0.,1.,1.}}
+};
+static FttDirection corner[8][3] = {
+  {FTT_LEFT, FTT_BOTTOM, FTT_BACK},
+  {FTT_LEFT, FTT_BOTTOM, FTT_FRONT},
+  {FTT_LEFT, FTT_TOP, FTT_BACK},
+  {FTT_LEFT, FTT_TOP, FTT_FRONT},
+  {FTT_RIGHT, FTT_BOTTOM, FTT_BACK},
+  {FTT_RIGHT, FTT_BOTTOM, FTT_FRONT},
+  {FTT_RIGHT, FTT_TOP, FTT_BACK},
+  {FTT_RIGHT, FTT_TOP, FTT_FRONT}
+};
+static guint connectv[12][2][4] = {
+  {{4, 5, 1, 0}, {0, 2, 6, 4}}, /* 0 */
+  {{5, 7, 3, 1}, {1, 0, 4, 5}}, /* 1 */
+  {{7, 6, 2, 3}, {3, 1, 5, 7}}, /* 2 */
+  {{6, 4, 0, 2}, {2, 3, 7, 6}}, /* 3 */
+  {{2, 6, 4, 0}, {0, 1, 3, 2}}, /* 4 */
+  {{3, 2, 0, 1}, {1, 5, 7, 3}}, /* 5 */
+  {{7, 3, 1, 5}, {5, 4, 6, 7}}, /* 6 */
+  {{6, 7, 5, 4}, {4, 0, 2, 6}}, /* 7 */
+  {{1, 3, 2, 0}, {0, 4, 5, 1}}, /* 8 */
+  {{5, 1, 0, 4}, {4, 6, 7, 5}}, /* 9 */
+  {{7, 5, 4, 6}, {6, 2, 3, 7}}, /* 10 */
+  {{3, 7, 6, 2}, {2, 0, 1, 3}}  /* 11 */
+};
+static FttVector cvertex[8] = {
+  {0., 0., 0.}, {0., 0., 1.}, {0., 1., 0.}, {0., 1., 1.},
+  {1., 0., 0.}, {1., 0., 1.}, {1., 1., 0.}, {1., 1., 1.}
+};
+
+#define SLIGHTLY_LARGER 1.001
diff --git a/src/levelset.c b/src/levelset.c
new file mode 100644
index 0000000..188b72e
--- /dev/null
+++ b/src/levelset.c
@@ -0,0 +1,220 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2006 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "levelset.h"
+#include "vof.h"
+
+/* GfsVariableDistance: object */
+
+static void variable_distance_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain;
+
+  (* GTS_OBJECT_CLASS (gfs_variable_distance_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (c)");
+    return;
+  }
+  domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (!(GFS_VARIABLE_DISTANCE (*o)->v = 
+	gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  if (GFS_VARIABLE1 (*o)->description)
+    g_free (GFS_VARIABLE1 (*o)->description);
+  GFS_VARIABLE1 (*o)->description = g_strjoin (" ", 
+					       "Distance to the interface defined by tracer",
+					       fp->token->str, NULL);
+  gts_file_next_token (fp);
+
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_INT, "stencil", TRUE},
+      {GTS_NONE}
+    };
+    var[0].data = &GFS_VARIABLE_DISTANCE (*o)->stencil; 
+    gts_file_assign_variables (fp, var);
+  }
+}
+
+static void variable_distance_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_distance_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s", GFS_VARIABLE_DISTANCE (o)->v->name);
+  if (GFS_VARIABLE_DISTANCE (o)->stencil)
+    fputs (" { stencil = 1 }", fp);
+}
+
+static gdouble vof_distance2 (FttCell * cell, GtsPoint * t, gpointer v)
+{
+  gdouble f = GFS_VALUE (cell, GFS_VARIABLE1 (v));
+  
+  if (GFS_IS_FULL (f))
+    return G_MAXDOUBLE;
+  if (!FTT_CELL_IS_LEAF (cell))
+    return ftt_cell_point_distance2_min (cell, t);
+  else
+    return gfs_vof_facet_distance2 (cell, v, t);
+}
+
+static void distance_for_stencil (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsVariable * s2 = data[2];
+
+  if (GFS_VALUE (cell, s2)) {
+    GfsVariableDistance * l = GFS_VARIABLE_DISTANCE (v);
+    GtsPoint p;
+    gdouble d2;
+    
+    ftt_cell_pos (cell, (FttVector *) &p.x);
+    d2 = gfs_domain_cell_point_distance2 (v->domain, &p, vof_distance2, l->v, NULL);
+    GFS_VALUE (cell, v) = GFS_VALUE (cell, l->v) > 0.5 ? sqrt (d2) : -sqrt (d2);
+  }
+  else
+    GFS_VALUE (cell, v) = G_MAXDOUBLE;
+}
+
+static void distance (FttCell * cell, GfsVariable * v)
+{
+  GfsVariableDistance * l = GFS_VARIABLE_DISTANCE (v);
+  GtsPoint p;
+  gdouble d2;
+    
+  ftt_cell_pos (cell, (FttVector *) &p.x);
+  d2 = gfs_domain_cell_point_distance2 (v->domain, &p, vof_distance2, l->v, NULL);
+  GFS_VALUE (cell, v) = GFS_VALUE (cell, l->v) > 0.5 ? sqrt (d2) : -sqrt (d2);
+}
+
+static void stencil_interpolate (FttCell * cell, gpointer * data)
+{
+  GfsVariableDistance * v = data[0];
+  gdouble f = GFS_VALUE (cell, v->v);
+  
+  if (!GFS_IS_FULL (f))
+    gfs_interpolate_stencil (cell, data[1]);
+}
+
+static void stencil_gradient (FttCell * cell, gpointer * data)
+{
+  GfsVariable * s1 = data[1];
+  GfsVariable * s2 = data[2];
+  FttComponent c;
+
+  if (GFS_VALUE (cell, s1))
+    for (c = 0; c < FTT_DIMENSION; c++)
+      gfs_center_gradient_stencil (cell, c, s2->i);
+}
+
+static void variable_distance_event_half (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariableDistance * v = GFS_VARIABLE_DISTANCE (event);
+
+  gfs_domain_timer_start (domain, "distance");
+
+  if (v->stencil) { /* fixme: this "acceleration technique"
+		       i.e. computing distance only in a band around
+		       the interface seems to be slower than computing
+		       the distance function everywhere! */
+    gpointer data[3], tmp;
+    data[0] = v;
+    data[1] = gfs_temporary_variable (domain);
+    data[2] = gfs_temporary_variable (domain);
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, data[1]);
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) stencil_interpolate, data);
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, data[2]);
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) stencil_gradient, data);
+    tmp = data[1]; data[1] = data[2]; data[2] = tmp;
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) stencil_gradient, data);
+
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) v->v->fine_coarse, v->v);
+    gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			 (FttCellTraverseFunc) distance_for_stencil, data,
+			 GFS_VARIABLE1 (event),GFS_VARIABLE1 (event));
+    gts_object_destroy (data[1]);
+    gts_object_destroy (data[2]);
+  }
+  else
+    gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			 (FttCellTraverseFunc) distance, v,
+			 GFS_VARIABLE1 (event),GFS_VARIABLE1 (event));
+
+  gfs_domain_timer_stop (domain, "distance");
+}
+
+static gboolean variable_distance_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_distance_class ())->parent_class)->event)
+      (event, sim)) {
+    if (!GFS_VARIABLE_DISTANCE (event)->first_done) {
+      variable_distance_event_half (event, sim);
+      GFS_VARIABLE_DISTANCE (event)->first_done = TRUE;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_distance_class_init (GtsObjectClass * klass)
+{
+  klass->read = variable_distance_read;
+  klass->write = variable_distance_write;
+  GFS_EVENT_CLASS (klass)->event = variable_distance_event;
+  GFS_EVENT_CLASS (klass)->event_half = variable_distance_event_half;
+}
+
+static void variable_distance_init (GfsVariable * v)
+{
+  v->units = 1.;
+}
+
+GfsVariableClass * gfs_variable_distance_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_distance_info = {
+      "GfsVariableDistance",
+      sizeof (GfsVariableDistance),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_distance_class_init,
+      (GtsObjectInitFunc) variable_distance_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_distance_info);
+  }
+
+  return klass;
+}
+
diff --git a/src/levelset.h b/src/levelset.h
new file mode 100644
index 0000000..bb84d16
--- /dev/null
+++ b/src/levelset.h
@@ -0,0 +1,55 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2006 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __LEVELSET_H__
+#define __LEVELSET_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "variable.h"
+
+/* GfsVariableDistance: header */
+
+typedef struct _GfsVariableDistance                GfsVariableDistance;
+
+struct _GfsVariableDistance {
+  /*< private >*/
+  GfsVariable parent;
+  gboolean first_done;
+
+  /*< public >*/
+  GfsVariable * v;
+  gboolean stencil;
+};
+
+#define GFS_VARIABLE_DISTANCE(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableDistance,\
+					           gfs_variable_distance_class ())
+#define GFS_IS_VARIABLE_DISTANCE(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_distance_class ()))
+
+GfsVariableClass * gfs_variable_distance_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LEVELSET_H__ */
diff --git a/src/m4.awk b/src/m4.awk
new file mode 100644
index 0000000..15e22e1
--- /dev/null
+++ b/src/m4.awk
@@ -0,0 +1,26 @@
+function replace_params(s, b,    i)
+{
+    for (i in b)
+	gsub(b[i], "($" i ")", s);
+    return s;
+}
+
+BEGIN {
+    print "m4_changecom()m4_dnl";
+}
+{
+    if ($1 == "GfsDefine" || $1 == "Define") {
+	macro = $2;
+	delete b;
+	if (match(macro, /(.+)\((.+)\)/, a)) {
+	    macro = a[1];
+	    split(a[2],b,",");
+	}
+	printf ("m4_define(`%s',`%s", macro, replace_params($3, b));
+	for (i = 4; i <= NF; i++)
+	    printf (" %s", replace_params($i, b));
+	printf ("')\n");
+    }
+    else
+	print $0;
+}
diff --git a/src/map.c b/src/map.c
new file mode 100644
index 0000000..f3c0a2f
--- /dev/null
+++ b/src/map.c
@@ -0,0 +1,244 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "map.h"
+
+/* GfsMap: Object */
+
+static void gfs_map_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsMap * map = GFS_MAP (*o);
+  GtsObjectClass * klass;
+  gboolean class_changed = FALSE;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsMapClass)");
+    return;
+  }
+  klass = gfs_object_class_from_name (fp->token->str);
+  if (klass == NULL) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_map_class ())) {
+    gts_file_error (fp, "`%s' is not a GfsMap", fp->token->str);
+    return;
+  }
+  if (klass != (*o)->klass) {
+    *o = gts_object_new (klass);
+    gts_object_destroy (GTS_OBJECT (map));
+    map = GFS_MAP (*o);
+    class_changed = TRUE;
+  }
+  gts_file_next_token (fp);
+}
+
+static void gfs_map_write (GtsObject * o, FILE * fp)
+{
+  fprintf (fp, "%s", o->klass->info.name);
+}
+
+static void gfs_map_class_init (GfsMapClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_map_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_map_write;
+}
+
+static void identity (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  *dest = *src;
+}
+
+static void gfs_map_init (GfsMap * map)
+{
+  map->transform = map->inverse = identity;
+}
+
+GfsMapClass * gfs_map_class (void)
+{
+  static GfsMapClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_map_info = {
+      "GfsMap",
+      sizeof (GfsMap),
+      sizeof (GfsMapClass),
+      (GtsObjectClassInitFunc) gfs_map_class_init,
+      (GtsObjectInitFunc) gfs_map_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
+				  &gfs_map_info);
+  }
+
+  return klass;
+}
+
+/* GfsMapFunction: Object */
+
+static void gfs_map_function_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_map_function_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    else {
+      static gchar name[3][3] = { "x:", "y:", "z:" };
+      FttComponent c;
+      for (c = 0; c < FTT_DIMENSION; c++)
+	if (!strcmp (fp->token->str, name[c]))
+	  break;
+      if (c == FTT_DIMENSION) {
+	gts_file_error (fp, "unknown keyword '%s'", fp->token->str);
+	return;
+      }
+      gts_file_next_token (fp);
+
+      GfsMapFunction * map = GFS_MAP_FUNCTION (*o);
+      if (!map->inverse[c])
+	map->inverse[c] = gfs_function_new (gfs_function_map_class (), 0.);
+      gfs_function_read (map->inverse[c], gfs_object_simulation (*o), fp);
+      if (fp->type == GTS_ERROR)
+	return;
+
+      if (fp->type != '\n') {
+	gts_file_error (fp, "expecting new line");
+	return;
+      }
+      while (fp->type == '\n')
+	gts_file_next_token (fp);
+	
+      if (!map->transform[c])
+	map->transform[c] = gfs_function_new (gfs_function_map_class (), 0.);
+      gfs_function_read (map->transform[c], gfs_object_simulation (*o), fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+  }
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void gfs_map_function_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_map_function_class ())->parent_class->write) (o, fp);
+  fputs (" {\n", fp);
+  GfsMapFunction * map = GFS_MAP_FUNCTION (o);
+  static gchar name[3][5] = { "  x:", "  y:", "  z:" };
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (map->transform[c]) {
+      fputs (name[c], fp);
+      gfs_function_write (map->inverse[c], fp);
+      fputs ("\n    ", fp);
+      gfs_function_write (map->transform[c], fp);
+      fputc ('\n', fp);
+    }
+  fputc ('}', fp);
+}
+
+static void gfs_map_function_destroy (GtsObject * o)
+{
+  GfsMapFunction * map = GFS_MAP_FUNCTION (o);
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    if (map->transform[c])
+      gts_object_destroy (GTS_OBJECT (map->transform[c]));
+    if (map->inverse[c])
+      gts_object_destroy (GTS_OBJECT (map->inverse[c]));
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_map_function_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_map_function_class_init (GfsMapClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_map_function_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_map_function_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_map_function_destroy;
+}
+
+static void map_function_transform (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  GfsMapFunction * mf = GFS_MAP_FUNCTION (map);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (mf->transform[c])
+      (&dest->x)[c] = gfs_function_spatial_value (mf->transform[c], src);
+    else
+      (&dest->x)[c] = (&src->x)[c];
+}
+
+static void map_function_inverse (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  GfsMapFunction * mf = GFS_MAP_FUNCTION (map);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (mf->inverse[c])
+      (&dest->x)[c] = gfs_function_spatial_value (mf->inverse[c], src);
+    else
+      (&dest->x)[c] = (&src->x)[c];
+}
+
+static void gfs_map_function_init (GfsMap * map)
+{
+  map->transform = map_function_transform;
+  map->inverse =   map_function_inverse;
+}
+
+GfsMapClass * gfs_map_function_class (void)
+{
+  static GfsMapClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_map_function_info = {
+      "GfsMapFunction",
+      sizeof (GfsMapFunction),
+      sizeof (GfsMapClass),
+      (GtsObjectClassInitFunc) gfs_map_function_class_init,
+      (GtsObjectInitFunc) gfs_map_function_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_map_class ()), &gfs_map_function_info);
+  }
+
+  return klass;
+}
diff --git a/src/map.h b/src/map.h
new file mode 100644
index 0000000..7d23d95
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,87 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __MAP_H__
+#define __MAP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "variable.h"
+#include "utils.h"
+
+/* GfsMap: Header */
+
+typedef struct _GfsMap         GfsMap;
+
+struct _GfsMap {
+  /*< private >*/
+  GtsSListContainee parent;
+
+  void (* transform) (GfsMap * map, const FttVector * src, FttVector * dest);
+  void (* inverse)   (GfsMap * map, const FttVector * src, FttVector * dest);
+  /*< public >*/
+};
+
+typedef struct _GfsMapClass    GfsMapClass;
+
+struct _GfsMapClass {
+  /*< private >*/
+  GtsSListContaineeClass parent_class;
+
+  /*< public >*/
+};
+
+#define GFS_MAP(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsMap,\
+					         gfs_map_class ())
+#define GFS_MAP_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsMapClass,\
+						 gfs_map_class())
+#define GFS_IS_MAP(obj)         (gts_object_is_from_class (obj,\
+						 gfs_map_class ()))
+
+GfsMapClass * gfs_map_class      (void);
+
+/* GfsMapFunction: Header */
+
+typedef struct _GfsMapFunction         GfsMapFunction;
+
+struct _GfsMapFunction {
+  /*< private >*/
+  GfsMap parent;
+
+  /*< public >*/
+  GfsFunction * transform[FTT_DIMENSION], * inverse[FTT_DIMENSION];
+};
+
+#define GFS_MAP_FUNCTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsMapFunction,\
+					         gfs_map_function_class ())
+#define GFS_IS_MAP_FUNCTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_map_function_class ()))
+
+GfsMapClass * gfs_map_function_class      (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MAP_H__ */
diff --git a/src/metric.c b/src/metric.c
new file mode 100644
index 0000000..7cf2c53
--- /dev/null
+++ b/src/metric.c
@@ -0,0 +1,868 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "metric.h"
+#include <complex.h>
+#include "map.h"
+#include "solid.h"
+
+/* GfsVariableMetric */
+
+GfsVariableClass * gfs_variable_metric_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_metric_info = {
+      "GfsVariableMetric",
+      sizeof (GfsVariable),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_metric_info);
+  }
+
+  return klass;
+}
+
+/* "Expanded spherical cube" metric */
+
+#define N 30
+
+#if 0
+/* Conformal mapping Taylor coefficients: from Rancic et al, 1996, Table B.1 */
+
+static double A[N] = {
+   1.47713062600964, -0.38183510510174, -0.05573058001191, -0.01895883606818, -0.00791315785221,
+  -0.00486625437708, -0.00329251751279, -0.00235481488325, -0.00175870527475, -0.00135681133278,
+  -0.00107459847699, -0.00086944475948, -0.00071607115121, -0.00059867100093, -0.00050699063239,
+  -0.00043415191279, -0.00037541003286, -0.00032741060100, -0.00028773091482, -0.00025458777519,
+  -0.00022664642371, -0.00020289261022, -0.00018254510830, -0.00016499474461, -0.00014976117168,
+  -0.00013646173946, -0.00012478875823, -0.00011449267279, -0.00010536946150, -0.00009725109376
+};
+
+static double B[N] = {
+  0.67698819751739, 0.11847293456554, 0.05317178134668, 0.02965810434052, 0.01912447304028,
+  0.01342565621117, 0.00998873323180, 0.00774868996406, 0.00620346979888, 0.00509010874883,
+  0.00425981184328, 0.00362308956077, 0.00312341468940, 0.00272360948942, 0.00239838086555,
+  0.00213001905118, 0.00190581316131, 0.00171644156404, 0.00155493768255, 0.00141600715207,
+  0.00129556597754, 0.00119042140226, 0.00109804711790, 0.00101642216628, 0.00094391366522,
+  0.00087919021224, 0.00082115710311, 0.00076890728775, 0.00072168382969, 0.00067885087750
+};
+
+#else
+/* Conformal mapping Taylor coefficients: from map_xy2xyz.m from mitgcm */
+
+static double A[N] = {
+  1.47713057321600, -0.38183513110512, -0.05573055466344, -0.01895884801823, -0.00791314396396,
+  -0.00486626515498, -0.00329250387158, -0.00235482619663, -0.00175869000970, -0.00135682443774,
+  -0.00107458043205, -0.00086946107050, -0.00071604933286, -0.00059869243613, -0.00050696402446,
+  -0.00043418115349, -0.00037537743098, -0.00032745130951, -0.00028769063795, -0.00025464473946,
+  -0.00022659577923, -0.00020297175587, -0.00018247947703, -0.00016510295548, -0.00014967258633,
+  -0.00013660647356, -0.00012466390509, -0.00011468147908, -0.00010518717478, -0.00009749136078
+};
+
+static double B[N] = {
+  0.67698822171341, 0.11847295533659, 0.05317179075349, 0.02965811274764, 0.01912447871071,
+  0.01342566129383, 0.00998873721022, 0.00774869352561, 0.00620347278164, 0.00509011141874,
+  0.00425981415542, 0.00362309163280, 0.00312341651697, 0.00272361113245, 0.00239838233411,
+  0.00213002038153, 0.00190581436893, 0.00171644267546, 0.00155493871562, 0.00141600812949,
+  0.00129556691848, 0.00119042232809, 0.00109804804853, 0.00101642312253, 0.00094391466713,
+  0.00087919127990, 0.00082115825576, 0.00076890854394, 0.00072168520663, 0.00067885239089
+};
+#endif
+
+static complex WofZ (complex Z)
+{
+  complex W = 0.;
+  int n = N;
+  while (n-- > 0)
+    W = (W + A[n])*Z;
+  return W;
+}
+
+static complex ZofW (complex W)
+{
+  complex Z = 0.;
+  int n = N;
+  while (n-- > 0)
+    Z = (Z + B[n])*W;
+  return Z;
+}
+
+/* I^(1/3) */
+#define I3 (0.86602540378444 + I/2.)
+/* sqrt (3.) - 1. */
+#define RA 0.73205080756888
+
+/* Conformal mapping of a cube face onto a sphere. Maps (x,y) on the
+ * north-pole face of a cube to (X,Y,Z) coordinates in physical space.
+ *
+ * Based on f77 code from Jim Purser & Misha Rancic.
+ *
+ * Face is oriented normal to Z-axis with X and Y increasing with x
+ * and y.
+ */
+static void fmap_xy2XYZ (double x, double y, double * X, double * Y, double * Z)
+{
+  int kx = x < 0., ky = y < 0.;
+  x = fabs (x); y = fabs (y);
+  int kxy = y > x;
+
+  if (kxy) {
+    double tmp = x;
+    x = 1. - y;
+    y = 1. - tmp;
+  }
+  else {
+    x = 1. - x;
+    y = 1. - y;
+  }
+
+  complex z = (x + I*y)/2.;
+  complex W;
+  if (cabs (z) > 0.) {
+    z = z*z*z*z;
+    W = WofZ (z);
+    W = I3*cpow (W*I, 1./3.);
+  }
+  else
+    W = 0.;
+  complex cb = I - 1.;
+  complex cc = RA*cb/2.;
+  W = (W - RA)/(cb + cc*W);
+  *X = creal (W);
+  *Y = cimag (W);
+  double H = 2./(1. + (*X)*(*X) + (*Y)*(*Y));
+  *X *= H;
+  *Y *= H;
+  *Z = H - 1.;
+  
+  if (kxy) {
+    double tmp = *X;
+    *X = *Y;
+    *Y = tmp;
+  }
+  if (kx)
+    *X = - *X;
+  if (ky)
+    *Y = - *Y;
+}
+
+/* Conformal mapping of a cube onto a sphere. Maps (x,y) on the
+ * 6 faces of the cube to (X,Y,Z) coordinates in physical space.
+ *
+ * Based on f77 code from Jim Purser & Misha Rancic.
+ *
+ * Face 1 is oriented normal to Z-axis with X and Y increasing with x
+ * and y (see doc/figures/cubed.fig).
+ *
+ * returns: FALSE if the input coordinates are invalid, TRUE otherwise.
+ */
+static void cmap_xy2XYZ (double x, double y, double * X, double * Y, double * Z)
+{
+  x *= 2.; y *= 2.;
+
+  /* symmetries: see doc/figures/cubed.fig */
+  double tmp;
+  if (y <= 1. && x <= 3.) {
+    if (x <= 1.) /* face 1 */
+      fmap_xy2XYZ (x, y, X, Y, Z);
+    else { /* face 2 */
+      fmap_xy2XYZ (x - 2., y, X, Y, Z);
+      tmp = *X;
+      *X = *Z; *Z = - tmp;
+    }
+  }
+  else if (y <= 3. && x <= 5.) {
+    if (x <= 3.) { /* face 3 */
+      fmap_xy2XYZ (x - 2., y - 2., X, Y, Z);
+      tmp = *X;
+      *X = -*Y; *Y = *Z; *Z = - tmp;
+    }
+    else { /* face 4 */
+      fmap_xy2XYZ (x - 4., y - 2., X, Y, Z);
+      tmp = *Y;
+      *Z = - *Z; *Y = - *X; *X = - tmp;
+    }
+  }
+  else {
+    if (x <= 5.) { /* face 5 */
+      fmap_xy2XYZ (x - 4., y - 4., X, Y, Z);
+      tmp = *Z;
+      *Z = *Y; *Y = - *X; *X = - tmp;
+    }
+    else { /* face 6 */
+      fmap_xy2XYZ (x - 6., y - 4., X, Y, Z);
+      tmp = *Y;
+      *Y = - *Z; *Z = tmp;
+    }
+  }
+}
+
+/* Conformal mapping of a sphere onto a cube face. Maps (X,Y,Z) coordinates
+ * in physical space to (x,y) on the north-pole face of a cube.
+ *
+ * This is the inverse transform of fmap_xy2XYZ().
+ */
+static void fmap_XYZ2xy (double X, double Y, double Z, double * x, double * y)
+{
+  int kx = X < 0., ky = Y < 0.;
+  X = fabs (X); Y = fabs (Y);
+  int kxy = Y > X;
+
+  if (kxy) {
+    double tmp = X;
+    X = Y;
+    Y = tmp;
+  }
+
+  double H = Z + 1.;
+  X /= H; Y /= H;
+  complex W = X + Y*I;
+  complex cb = I - 1.;
+  complex cc = RA*cb/2.;
+  W = (W*cb + RA)/(1. - W*cc);
+  W = W/I3;
+  W = W*W*W;
+  W /= I;
+  complex z = ZofW (W);
+  z = cpow (z, 1./4.)*2.;
+  *x = fabs (creal (z));
+  *y = fabs (cimag (z));
+
+  if (kxy) {
+    *x = 1. - *x;
+    *y = 1. - *y;
+  }
+  else {
+    double tmp = *x;
+    *x = 1. - *y;
+    *y = 1. - tmp;
+  }
+  if (kx)
+    *x = - *x;
+  if (ky)
+    *y = - *y;
+}
+
+static double angle_between_vectors (const double v1[3], const double v2[3])
+{
+  return acos (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]);
+}
+
+static void plane_normal (const double p1[3], const double p2[3], double plane[3])
+{
+  plane[0] = p1[1]*p2[2] - p1[2]*p2[1];
+  plane[1] = p1[2]*p2[0] - p1[0]*p2[2];
+  plane[2] = p1[0]*p2[1] - p1[1]*p2[0];
+  double mag = sqrt (plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]);
+  plane[0] /= mag;
+  plane[1] /= mag;
+  plane[2] /= mag;
+}
+
+static double excess_of_quad (const double v1[3], const double v2[3],
+			      const double v3[3], const double v4[3])
+{
+  double plane1[3], plane2[3], plane3[3], plane4[3];
+
+  plane_normal (v1, v2, plane1);
+  plane_normal (v2, v3, plane2);
+  plane_normal (v3, v4, plane3);
+  plane_normal (v4, v1, plane4);
+  
+  return 2.*M_PI -
+    angle_between_vectors (plane2, plane1) -
+    angle_between_vectors (plane3, plane2) -
+    angle_between_vectors (plane4, plane3) -
+    angle_between_vectors (plane1, plane4);
+}
+
+/* GfsMapCubed: Object */
+
+static void gfs_map_cubed_read (GtsObject ** o, GtsFile * fp)
+{
+  /* this mapping cannot be used independently from GfsMetricCubed */
+}
+
+static void gfs_map_cubed_write (GtsObject * o, FILE * fp)
+{
+  /* this mapping cannot be used independently from GfsMetricCubed */
+}
+
+static void gfs_map_cubed_class_init (GfsMapClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_map_cubed_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_map_cubed_write;
+}
+
+static void map_cubed_transform (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  GfsSimulation * sim = gfs_object_simulation (map);
+  double lon = src->x*M_PI/180., lat = src->y*M_PI/180.;
+  double X = cos (lat)*sin (lon), Y = sin (lat), Z = sqrt (1. - X*X - Y*Y);
+  double x, y;
+  /* fixme: only works for face 1 */
+  fmap_XYZ2xy (X, Y, Z, &x, &y);
+  dest->x = x/2.*sim->physical_params.L;
+  dest->y = y/2.*sim->physical_params.L;
+  dest->z = src->z;
+}
+
+static void map_cubed_inverse (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  GfsSimulation * sim = gfs_object_simulation (map);
+  double X, Y, Z;
+  cmap_xy2XYZ (src->x/sim->physical_params.L, src->y/sim->physical_params.L, &X, &Y, &Z);
+  dest->x = atan2 (X, Z)*180./M_PI;
+  dest->y = asin (Y)*180./M_PI;
+  dest->z = src->z;
+}
+
+static void gfs_map_cubed_init (GfsMap * map)
+{
+  map->transform = map_cubed_transform;
+  map->inverse =   map_cubed_inverse;
+}
+
+static GfsMapClass * gfs_map_cubed_class (void)
+{
+  static GfsMapClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_map_cubed_info = {
+      "GfsMapCubed",
+      sizeof (GfsMap),
+      sizeof (GfsMapClass),
+      (GtsObjectClassInitFunc) gfs_map_cubed_class_init,
+      (GtsObjectInitFunc) gfs_map_cubed_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_map_class ()), &gfs_map_cubed_info);
+  }
+
+  return klass;
+}
+
+/* GfsMetricCubed: Object */
+
+static gdouble cubed_face_metric (const GfsDomain * domain, const FttCellFace * face)
+{
+  if (face->d/2 > 1)
+    return 1.;
+  return GFS_VALUE (face->cell, GFS_METRIC_CUBED (domain->metric_data)->h[face->d]);
+}
+
+static gdouble cubed_cell_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  return GFS_VALUE (cell, GFS_VARIABLE1 (domain->metric_data));
+}
+
+static gdouble cubed_solid_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  g_assert (GFS_IS_MIXED (cell));
+  g_assert_not_implemented ();
+  return 1.;
+}
+
+static gdouble cubed_scale_metric (const GfsDomain * domain, const FttCell * cell, FttComponent c)
+{
+  if (c > FTT_Y)
+    return 1.;
+  FttComponent d = FTT_ORTHOGONAL_COMPONENT (c);
+  return (GFS_VALUE (cell, GFS_METRIC_CUBED (domain->metric_data)->h[2*d]) +
+	  GFS_VALUE (cell, GFS_METRIC_CUBED (domain->metric_data)->h[2*d + 1]))/2.;
+}
+
+static void none (FttCell * parent, GfsVariable * v)
+{
+}
+
+typedef struct {
+  double x, y, x1, y1, z1;
+  double a;
+} Point;
+
+typedef struct {
+  Point * v[4];
+  double a, h[4];
+} Square;
+
+static void point_new (Point * p, double x, double y)
+{
+  p->x = x; p->y = y;
+  cmap_xy2XYZ (x, y, &p->x1, &p->y1, &p->z1);
+}
+
+static Point ** matrix_refine (Point ** m, int n)
+{
+  int n1 = 2*n - 1, i, j;
+  Point ** r = gfs_matrix_new (n1, n1, sizeof (Point));
+  for (i = 0; i < n; i++)
+    for (j = 0; j < n; j++)
+      r[2*i][2*j] = m[i][j];
+  for (i = 0; i < n - 1; i++)
+    for (j = 0; j < n - 1; j++) {
+      point_new (&r[2*i+1][2*j], (m[i][j].x + m[i+1][j].x)/2., m[i][j].y);
+      point_new (&r[2*i][2*j+1], m[i][j].x, (m[i][j].y + m[i][j+1].y)/2.);
+      point_new (&r[2*i+1][2*j+1], (m[i][j].x + m[i+1][j].x)/2., (m[i][j].y + m[i][j+1].y)/2.);
+    }
+  i = n - 1;
+  for (j = 0; j < n - 1; j++)
+    point_new (&r[2*i][2*j+1], m[i][j].x, (m[i][j].y + m[i][j+1].y)/2.);
+  j = n - 1;
+  for (i = 0; i < n - 1; i++)
+    point_new (&r[2*i+1][2*j], (m[i][j].x + m[i+1][j].x)/2., m[i][j].y);
+  gfs_matrix_free (m);
+  return r;
+}
+
+static Point ** matrix_from_cell (FttCell * cell)
+{
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  double h = ftt_cell_size (cell)/2.;
+  Point ** r = gfs_matrix_new (2, 2, sizeof (Point));
+  point_new (&r[0][0], p.x - h, p.y - h);
+  point_new (&r[1][0], p.x + h, p.y - h);
+  point_new (&r[1][1], p.x + h, p.y + h);
+  point_new (&r[0][1], p.x - h, p.y + h);
+  return r;
+}
+
+static double matrix_a (Point ** r, int m, int i0, int j0)
+{
+  int i, j;
+  double a = 0.;
+  double h = r[m][0].x - r[0][0].x;
+  for (i = 0; i < m; i++)
+    for (j = 0; j < m; j++)
+      a += excess_of_quad (&r[i0+i][j0+j].x1, &r[i0+i+1][j0+j].x1,
+			   &r[i0+i+1][j0+j+1].x1, &r[i0+i][j0+j+1].x1);
+  return 4.*a/(M_PI*M_PI*h*h);
+}
+
+static double matrix_hx (Point ** r, int m, int i0, int j0)
+{
+  int i;
+  double hx = 0.;
+  double h = r[m][0].x - r[0][0].x;
+  for (i = 0; i < m; i++)
+    hx += angle_between_vectors (&r[i0+i][j0].x1, &r[i0+i+1][j0].x1);
+  return 2.*hx/(M_PI*h);
+}
+
+static double matrix_hy (Point ** r, int m, int i0, int j0)
+{
+  int j;
+  double hy = 0.;
+  double h = r[m][0].x - r[0][0].x;
+  for (j = 0; j < m; j++)
+    hy += angle_between_vectors (&r[i0][j0+j].x1, &r[i0][j0+j+1].x1);
+  return 2.*hy/(M_PI*h);
+}
+
+static void cubed_coarse_fine (FttCell * parent, GfsVariable * a)
+{
+  if (GFS_CELL_IS_BOUNDARY (parent))
+    return;
+
+  GfsMetricCubed * cubed = GFS_METRIC_CUBED (a);
+  Point ** r = matrix_from_cell (parent);
+  r = matrix_refine (r, 2);
+  int n = 3, level = cubed->level - (ftt_cell_level (parent) + 1);
+  while (level-- > 0) {
+    r = matrix_refine (r, n);
+    n = 2*n - 1;
+  }
+
+  FttCellChildren child;
+  ftt_cell_children (parent, &child);
+  int m = n/2;
+
+  GFS_VALUE (child.c[0], a) = matrix_a (r, m, 0, m);
+  GFS_VALUE (child.c[1], a) = matrix_a (r, m, m, m);
+  GFS_VALUE (child.c[2], a) = matrix_a (r, m, 0, 0);
+  GFS_VALUE (child.c[3], a) = matrix_a (r, m, m, 0);
+
+  GFS_VALUE (child.c[0], cubed->h[0]) = GFS_VALUE (child.c[1], cubed->h[1]) = 
+    matrix_hy (r, m, m, m);
+  GFS_VALUE (child.c[0], cubed->h[3]) = GFS_VALUE (child.c[2], cubed->h[2]) = 
+    matrix_hx (r, m, 0, m);
+  GFS_VALUE (child.c[2], cubed->h[0]) = GFS_VALUE (child.c[3], cubed->h[1]) = 
+    matrix_hy (r, m, m, 0);
+  GFS_VALUE (child.c[1], cubed->h[3]) = GFS_VALUE (child.c[3], cubed->h[2]) = 
+    matrix_hx (r, m, m, m);
+
+  GFS_VALUE (child.c[0], cubed->h[2]) = matrix_hx (r, m, 0, n - 1);
+  GFS_VALUE (child.c[0], cubed->h[1]) = matrix_hy (r, m, 0, m);
+  GFS_VALUE (child.c[1], cubed->h[2]) = matrix_hx (r, m, m, n - 1);
+  GFS_VALUE (child.c[1], cubed->h[0]) = matrix_hy (r, m, n - 1, m);
+  GFS_VALUE (child.c[2], cubed->h[3]) = matrix_hx (r, m, 0, 0);
+  GFS_VALUE (child.c[2], cubed->h[1]) = matrix_hy (r, m, 0, 0);
+  GFS_VALUE (child.c[3], cubed->h[0]) = matrix_hy (r, m, n - 1, 0);
+  GFS_VALUE (child.c[3], cubed->h[3]) = matrix_hx (r, m, m, 0);
+
+  gfs_matrix_free (r);
+}
+
+static void cubed_fine_coarse (FttCell * parent, GfsVariable * a)
+{
+  GfsMetricCubed * cubed = GFS_METRIC_CUBED (a);
+  FttCellChildren child;
+  guint n;
+
+  ftt_cell_children (parent, &child);
+  gdouble va = 0.;
+  for (n = 0; n < 4; n++)
+    va += GFS_VALUE (child.c[n], a);
+  GFS_VALUE (parent, a) = va/4;
+
+  GFS_VALUE (parent, cubed->h[0]) = (GFS_VALUE (child.c[1], cubed->h[0]) +
+				     GFS_VALUE (child.c[3], cubed->h[0]))/2.;
+  GFS_VALUE (parent, cubed->h[1]) = (GFS_VALUE (child.c[0], cubed->h[1]) +
+				     GFS_VALUE (child.c[2], cubed->h[1]))/2.;
+  GFS_VALUE (parent, cubed->h[2]) = (GFS_VALUE (child.c[0], cubed->h[2]) +
+				     GFS_VALUE (child.c[1], cubed->h[2]))/2.;
+  GFS_VALUE (parent, cubed->h[3]) = (GFS_VALUE (child.c[2], cubed->h[3]) +
+				     GFS_VALUE (child.c[3], cubed->h[3]))/2.;
+}
+
+static void metric_cubed_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_metric_cubed_class ())->parent_class->write) (o, fp);
+  if (GFS_METRIC_CUBED (o)->level != 0)
+    fprintf (fp, " %d", GFS_METRIC_CUBED (o)->level);
+}
+
+static void metric_cubed_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_metric_cubed_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (domain->metric_data || domain->face_metric || domain->cell_metric || domain->solid_metric) {
+    gts_file_error (fp, "cannot use multiple metrics (yet)");
+    return;
+  }
+
+  GfsVariable * a = GFS_VARIABLE1 (*o);
+  GfsMetricCubed * cubed = GFS_METRIC_CUBED (a);
+  if (fp->type == GTS_INT) {
+    cubed->level = atoi (fp->token->str);
+    gts_file_next_token (fp);
+  }
+
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    gchar * name = g_strdup_printf ("%sh%d", a->name, d);
+    cubed->h[d] = gfs_domain_get_or_add_variable (domain, name, "Cubed face metric");
+    cubed->h[d]->fine_coarse = cubed->h[d]->coarse_fine = none;
+    g_free (name);
+  }
+  g_free (a->description);
+  a->description = g_strdup ("Cubed cell metric");
+  a->coarse_fine = cubed_coarse_fine;
+  a->fine_coarse = cubed_fine_coarse;
+
+  GtsObject * map = gts_object_new (GTS_OBJECT_CLASS (gfs_map_cubed_class ()));
+  gfs_object_simulation_set (map, domain);
+  gts_container_add (GTS_CONTAINER (GFS_SIMULATION (domain)->maps), GTS_CONTAINEE (map));
+
+  domain->metric_data  = cubed;
+  domain->face_metric  = cubed_face_metric;
+  domain->cell_metric  = cubed_cell_metric;
+  domain->solid_metric = cubed_solid_metric;
+  domain->scale_metric = cubed_scale_metric;
+}
+
+static void metric_cubed_class_init (GtsObjectClass * klass)
+{
+  klass->read = metric_cubed_read;
+  klass->write = metric_cubed_write;
+}
+
+GfsVariableClass * gfs_metric_cubed_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_metric_cubed_info = {
+      "GfsMetricCubed",
+      sizeof (GfsMetricCubed),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) metric_cubed_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_metric_class ()), 
+				  &gfs_metric_cubed_info);
+  }
+
+  return klass;
+}
+
+/* GfsMapLonLat: Header */
+
+typedef struct _GfsMapLonLat         GfsMapLonLat;
+
+struct _GfsMapLonLat {
+  /*< private >*/
+  GfsMap parent;
+
+  /*< public >*/
+  gdouble r;
+};
+
+#define GFS_MAP_LONLAT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsMapLonLat,\
+					         gfs_map_lonlat_class ())
+#define GFS_IS_MAP_LONLAT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_map_lonlat_class ()))
+
+static GfsMapClass * gfs_map_lonlat_class      (void);
+
+/* GfsMapLonLat: Object */
+
+static void gfs_map_lonlat_read (GtsObject ** o, GtsFile * fp)
+{
+  /* this mapping cannot be used independently from GfsMetricLonLat */
+}
+
+static void gfs_map_lonlat_write (GtsObject * o, FILE * fp)
+{
+  /* this mapping cannot be used independently from GfsMetricLonLat */
+}
+
+static void gfs_map_lonlat_class_init (GfsMapClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_map_lonlat_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_map_lonlat_write;
+}
+
+static void map_lonlat_transform (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  dest->x = src->x*M_PI/180.*GFS_MAP_LONLAT (map)->r;
+  dest->y = src->y*M_PI/180.*GFS_MAP_LONLAT (map)->r;
+  dest->z = src->z;
+}
+
+static void map_lonlat_inverse (GfsMap * map, const FttVector * src, FttVector * dest)
+{
+  dest->x = src->x*180./(M_PI*GFS_MAP_LONLAT (map)->r);
+  dest->y = src->y*180./(M_PI*GFS_MAP_LONLAT (map)->r);
+  dest->z = src->z;
+}
+
+static void gfs_map_lonlat_init (GfsMap * map)
+{
+  map->transform = map_lonlat_transform;
+  map->inverse =   map_lonlat_inverse;
+  GFS_MAP_LONLAT (map)->r = 1.;
+}
+
+static GfsMapClass * gfs_map_lonlat_class (void)
+{
+  static GfsMapClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_map_lonlat_info = {
+      "GfsMapLonLat",
+      sizeof (GfsMapLonLat),
+      sizeof (GfsMapClass),
+      (GtsObjectClassInitFunc) gfs_map_lonlat_class_init,
+      (GtsObjectInitFunc) gfs_map_lonlat_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_map_class ()), &gfs_map_lonlat_info);
+  }
+
+  return klass;
+}
+
+/* GfsMetricLonLat: Object */
+
+static void metric_lon_lat_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_metric_lon_lat_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %g", GFS_METRIC_LON_LAT (o)->r);
+}
+
+static gdouble lon_lat_face_metric (const GfsDomain * domain, const FttCellFace * face)
+{
+  if (face->d/2 != FTT_Y)
+    return 1.;
+  return face->d == 2 ? 
+    GFS_VALUE (face->cell, GFS_METRIC_LON_LAT (domain->metric_data)->h2) :
+    GFS_VALUE (face->cell, GFS_METRIC_LON_LAT (domain->metric_data)->h3);
+}
+
+static gdouble lon_lat_cell_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  return GFS_VALUE (cell, GFS_VARIABLE1 (domain->metric_data));
+}
+
+static gdouble lon_lat_solid_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  g_assert (GFS_IS_MIXED (cell));
+  g_assert_not_implemented ();
+  return 1.;
+}
+
+static gdouble lon_lat_scale_metric (const GfsDomain * domain, const FttCell * cell, FttComponent c)
+{
+  if (c != FTT_X)
+    return 1.;
+  return GFS_VALUE (cell, GFS_VARIABLE1 (domain->metric_data));
+}
+
+static void lonlat_coarse_fine (FttCell * parent, GfsVariable * a)
+{
+  if (GFS_CELL_IS_BOUNDARY (parent))
+    return;
+
+  GfsMetricLonLat * lonlat = GFS_METRIC_LON_LAT (a);
+  FttCellChildren child;
+  ftt_cell_children (parent, &child);
+  FttVector p;
+  ftt_cell_pos (parent, &p);
+  double theta0 = gfs_object_simulation (lonlat)->physical_params.L/lonlat->r;
+  double theta = p.y*theta0;
+  double h = ftt_cell_size (parent);
+  double dtheta = h*theta0/2.;
+  double theta1 = theta + dtheta;
+  double theta2 = theta - dtheta;
+  double sintheta = sin (theta);
+
+  GFS_VALUE (child.c[0], a) = GFS_VALUE (child.c[1], a) = (sin (theta1) - sintheta)/dtheta;
+  GFS_VALUE (child.c[2], a) = GFS_VALUE (child.c[3], a) = (sintheta - sin (theta2))/dtheta;
+
+  GFS_VALUE (child.c[0], lonlat->h2) = GFS_VALUE (child.c[1], lonlat->h2) = cos (theta1);
+  GFS_VALUE (child.c[0], lonlat->h3) = GFS_VALUE (child.c[1], lonlat->h3) = 
+    GFS_VALUE (child.c[2], lonlat->h2) = GFS_VALUE (child.c[3], lonlat->h2) = 
+    cos (theta);
+  GFS_VALUE (child.c[2], lonlat->h3) = GFS_VALUE (child.c[3], lonlat->h3) = cos (theta2);
+}
+
+static void lonlat_fine_coarse (FttCell * parent, GfsVariable * a)
+{
+  GfsMetricLonLat * lonlat = GFS_METRIC_LON_LAT (a);
+  FttCellChildren child;
+  guint n;
+
+  ftt_cell_children (parent, &child);
+  gdouble va = 0.;
+  for (n = 0; n < 4; n++)
+    va += GFS_VALUE (child.c[n], a);
+  GFS_VALUE (parent, a) = va/4;
+
+  GFS_VALUE (parent, lonlat->h2) = (GFS_VALUE (child.c[0], lonlat->h2) +
+				    GFS_VALUE (child.c[1], lonlat->h2))/2.;
+  GFS_VALUE (parent, lonlat->h3) = (GFS_VALUE (child.c[3], lonlat->h3) +
+				    GFS_VALUE (child.c[2], lonlat->h3))/2.;
+}
+
+static void metric_lon_lat_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_metric_lon_lat_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (domain->metric_data || domain->face_metric || domain->cell_metric || domain->solid_metric) {
+    gts_file_error (fp, "cannot use multiple metrics (yet)");
+    return;
+  }
+
+  GFS_METRIC_LON_LAT (*o)->r = gfs_read_constant (fp, gfs_object_simulation (*o));
+  if (fp->type == GTS_ERROR)
+    return;
+  if (GFS_METRIC_LON_LAT (*o)->r <= 0.) {
+    gts_file_error (fp, "radius must be strictly positive");
+    return;
+  }
+
+  GfsVariable * a = GFS_VARIABLE1 (*o);
+  GfsMetricLonLat * lonlat = GFS_METRIC_LON_LAT (a);
+  gchar * name = g_strdup_printf ("%sh2", a->name);
+  lonlat->h2 = gfs_domain_get_or_add_variable (domain, name, "LonLat face metric");
+  lonlat->h2->coarse_fine = lonlat->h2->fine_coarse = none;
+  g_free (name);
+  name = g_strdup_printf ("%sh3", a->name);
+  lonlat->h3 = gfs_domain_get_or_add_variable (domain, name, "LonLat face metric");
+  lonlat->h3->coarse_fine = lonlat->h3->fine_coarse = none;
+  g_free (name);
+  g_free (a->description);
+  a->description = g_strdup ("LonLat cell metric");
+  a->coarse_fine = lonlat_coarse_fine;
+  a->fine_coarse = lonlat_fine_coarse;
+
+  GtsObject * map = gts_object_new (GTS_OBJECT_CLASS (gfs_map_lonlat_class ()));
+  gfs_object_simulation_set (map, domain);
+  gts_container_add (GTS_CONTAINER (GFS_SIMULATION (domain)->maps), GTS_CONTAINEE (map));
+  GFS_MAP_LONLAT (map)->r = GFS_METRIC_LON_LAT (*o)->r;
+
+  domain->metric_data = *o;
+  domain->face_metric  = lon_lat_face_metric;
+  domain->cell_metric  = lon_lat_cell_metric;
+  domain->solid_metric = lon_lat_solid_metric;
+  domain->scale_metric = lon_lat_scale_metric;
+}
+
+static void metric_lon_lat_class_init (GtsObjectClass * klass)
+{
+  klass->read = metric_lon_lat_read;
+  klass->write = metric_lon_lat_write;
+}
+
+static void metric_lon_lat_init (GfsMetricLonLat * m)
+{
+  m->r = 1.;
+}
+
+GfsVariableClass * gfs_metric_lon_lat_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_metric_lon_lat_info = {
+      "GfsMetricLonLat",
+      sizeof (GfsMetricLonLat),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) metric_lon_lat_class_init,
+      (GtsObjectInitFunc) metric_lon_lat_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_metric_class ()), 
+				  &gfs_metric_lon_lat_info);
+  }
+
+  return klass;
+}
diff --git a/src/metric.h b/src/metric.h
new file mode 100644
index 0000000..e2d6c36
--- /dev/null
+++ b/src/metric.h
@@ -0,0 +1,82 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __METRIC_H__
+#define __METRIC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "variable.h"
+
+/* GfsVariableMetric: Header */
+
+#define GFS_IS_VARIABLE_METRIC(obj)         (gts_object_is_from_class (obj,\
+						   gfs_variable_metric_class ()))
+
+GfsVariableClass * gfs_variable_metric_class  (void);
+
+/* GfsMetricCubed: Header */
+
+typedef struct _GfsMetricCubed GfsMetricCubed;
+
+struct _GfsMetricCubed {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsVariable * h[FTT_NEIGHBORS];
+  gint level;
+};
+
+#define GFS_METRIC_CUBED(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsMetricCubed,\
+					           gfs_metric_cubed_class ())
+#define GFS_IS_METRIC_CUBED(obj)         (gts_object_is_from_class (obj,\
+						   gfs_metric_cubed_class ()))
+
+GfsVariableClass * gfs_metric_cubed_class  (void);
+
+/* GfsMetricLonLat: Header */
+
+typedef struct _GfsMetricLonLat GfsMetricLonLat;
+
+struct _GfsMetricLonLat {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsVariable * h2, * h3;
+  gdouble r;
+};
+
+#define GFS_METRIC_LON_LAT(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsMetricLonLat,\
+					           gfs_metric_lon_lat_class ())
+#define GFS_IS_METRIC_LON_LAT(obj)         (gts_object_is_from_class (obj,\
+						   gfs_metric_lon_lat_class ()))
+
+GfsVariableClass * gfs_metric_lon_lat_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __METRIC_H__ */
diff --git a/src/moving.c b/src/moving.c
new file mode 100644
index 0000000..4591891
--- /dev/null
+++ b/src/moving.c
@@ -0,0 +1,976 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2005-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <gts.h>
+#include "moving.h"
+#include "simulation.h"
+#include "domain.h"
+#include "utils.h"
+#include "ftt.h"
+#include "refine.h"
+#include "adaptive.h"
+#include "solid.h"
+#include "vof.h"
+#include "surface.h"
+#include "advection.h"
+#include "source.h"
+
+#define OLD_SOLID(c) (*((GfsSolidVector **) &(GFS_VALUE (c, old_solid_v))))
+
+typedef struct {
+  GfsDomain * domain;
+  gdouble dt;
+  FttComponent c;
+  GfsVariable * div;
+  GfsVariable * v;
+} DivergenceData;
+
+#include "moving2.c"
+
+typedef struct {
+  GfsSimulation * sim;
+  GfsSolidMoving * s;
+  GfsVariable * old_solid_v, ** sold2, ** v;
+} SolidInfo;
+
+static double surface_value (FttCell * cell, GfsVariable * v, FttVector * ca)
+{
+  gdouble val = 0.;
+  if (!v->surface_bc)
+    /* default surface BC for velocity is zero */
+    return 0.;
+  else if (GFS_STATE (cell)->solid) {
+    FttVector oldca;
+    if (ca) {
+      oldca = GFS_STATE (cell)->solid->ca;
+      GFS_STATE (cell)->solid->ca = *ca;
+    }
+    (* GFS_SURFACE_GENERIC_BC_CLASS (GTS_OBJECT (v->surface_bc)->klass)->bc) (cell, v->surface_bc);
+    if (ca)
+      GFS_STATE (cell)->solid->ca = oldca;
+    val = GFS_STATE (cell)->solid->fv;
+  }
+  else {
+    GfsSolidVector solid;
+    if (ca)
+      solid.ca = *ca;
+    else
+      ftt_cell_pos (cell, &solid.ca);
+    solid.cm = solid.ca;
+    GFS_STATE (cell)->solid = &solid;
+    (* GFS_SURFACE_GENERIC_BC_CLASS (GTS_OBJECT (v->surface_bc)->klass)->bc) (cell, v->surface_bc);
+    GFS_STATE (cell)->solid = NULL;
+    val = solid.fv;
+  }
+  if (!(cell->flags & GFS_FLAG_DIRICHLET))
+    g_assert_not_implemented ();
+  return val;
+}
+
+static void init_new_cell_velocity_from_solid (FttCell * cell, SolidInfo * p)
+{
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    GFS_VALUE (cell, p->v[c]) = surface_value (cell, p->v[c], NULL);
+}
+
+static void update_neighbors (FttCell * cell)
+{
+  gint i;
+  FttCellNeighbors neighbor;
+  g_assert (cell);
+
+  ftt_cell_neighbors (cell, &neighbor);
+  for (i = 0; i < FTT_NEIGHBORS; i++)
+    if (neighbor.c[i] && neighbor.c[i]->children) {
+      ftt_cell_neighbors_not_cached (neighbor.c[i], &(neighbor.c[i]->children->neighbors));}
+}
+
+static gboolean refine_maxlevel (FttCell * cell, gint * maxlevel)
+{
+  return (ftt_cell_level (cell) < *maxlevel);
+}
+
+static void moving_cell_coarse_fine (FttCell * cell, GfsVariable * v)
+{
+  FttCell * parent = ftt_cell_parent (cell);
+
+  GFS_VALUE (cell, v) = GFS_VALUE (parent, v);
+  if (!GFS_CELL_IS_BOUNDARY (parent)) {
+    FttVector p;
+    FttComponent c;
+
+    ftt_cell_relative_pos (cell, &p);    
+    for (c = 0; c < FTT_DIMENSION; c++)
+      GFS_VALUE (cell, v) += (&p.x)[c]*gfs_center_van_leer_gradient (parent, c, v->i);
+  }
+}
+
+static void moving_cell_init (FttCell * cell, SolidInfo * solid_info)
+{
+  GSList * i;
+  gint k;
+  GfsDomain * domain = GFS_DOMAIN (solid_info->sim);
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (domain)->old_solid;
+
+  gfs_cell_init (cell, domain);
+
+  i = domain->variables;
+  while (i) {
+    GfsVariable * v = i->data;
+    
+    if (v->coarse_fine == (GfsVariableFineCoarseFunc) gfs_cell_coarse_fine)
+      moving_cell_coarse_fine (cell, v);
+    /* these are variables specific to moving solid boudaries */
+    else if (v->coarse_fine != sold2_fine_init && v != old_solid_v)
+      g_assert_not_implemented ();
+    i = i->next;
+  }
+
+  g_assert (OLD_SOLID (cell) == NULL);
+  OLD_SOLID (cell) = g_malloc0 (sizeof (GfsSolidVector));
+  OLD_SOLID (cell)->a = 0.;
+  GfsVariable ** sold2 = solid_info->sold2;
+  if (sold2)
+    for (k = 0; k < FTT_NEIGHBORS; k++)
+      SOLD2 (cell, k) = OLD_SOLID (cell)->s[k] = 0.;
+
+  init_new_cell_velocity_from_solid (cell, solid_info);
+}
+
+static void moving_cell_fine_init (FttCell * cell, SolidInfo * solid_info)
+{
+  GfsDomain * domain = GFS_DOMAIN(solid_info->sim);
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (domain)->old_solid;
+  GfsVariable ** sold2 = solid_info->sold2;
+  FttCellChildren child;
+  guint n;
+ 
+  gfs_cell_fine_init (cell, domain);
+
+  /* need to update the neighbors of the "undestroyed" parent cell */
+  update_neighbors (cell);
+ 
+  ftt_cell_children (cell, &child);
+  for (n = 0; n < FTT_CELLS; n++) {
+    GfsSolidVector * solid = OLD_SOLID (child.c[n]);
+    gint k;
+    g_assert (!solid);
+    solid = OLD_SOLID (child.c[n]) = g_malloc0 (sizeof (GfsSolidVector));
+    solid->a = 0.;
+    if (sold2)
+      for (k = 0; k < FTT_NEIGHBORS; k++)
+	SOLD2 (child.c[n], k) = solid->s[k] = 0.;
+  }
+}
+
+static void create_new_cells (FttCell * cell, GfsSurface * s, SolidInfo * solid_info)
+{
+  GfsSolidMoving * solid = solid_info->s;
+  gint maxlevel = gfs_function_value (solid->level, cell);
+
+  if (FTT_CELL_IS_DESTROYED (cell) && ftt_cell_level (cell) <= maxlevel) {
+    cell->flags &= ~FTT_FLAG_DESTROYED;
+    moving_cell_init (cell, solid_info);
+    if (ftt_cell_level (cell) < maxlevel)
+      ftt_cell_refine (cell,
+		       (FttCellRefineFunc) refine_maxlevel, &maxlevel,
+		       (FttCellInitFunc) moving_cell_fine_init, solid_info);
+  }
+  else if (ftt_cell_level (cell) < maxlevel)
+    ftt_cell_refine (cell,
+		     (FttCellRefineFunc) refine_maxlevel, &maxlevel,
+		     (FttCellInitFunc) gfs_cell_fine_init, solid_info->sim);
+}
+
+static void remesh_surface_moving (GfsSimulation * sim, GfsSolidMoving * s)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  SolidInfo solid_info;
+
+  solid_info.sim = sim;
+  solid_info.s = s;
+  solid_info.sold2 = GFS_SIMULATION_MOVING (sim)->sold2;
+  solid_info.v = gfs_domain_velocity (domain);
+  gfs_domain_traverse_cut (domain, GFS_SOLID (s)->s,
+			   FTT_POST_ORDER, FTT_TRAVERSE_LEAFS | FTT_TRAVERSE_DESTROYED,
+			   (FttCellTraverseCutFunc) create_new_cells, &solid_info);
+}
+
+static void solid_moving_destroy (GtsObject * object)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_SOLID_MOVING (object)->level));
+  (* GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class->destroy) (object);
+}
+
+static void solid_moving_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSolidMoving * solid = GFS_SOLID_MOVING (*o);
+  
+  if (GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (!GFS_IS_SURFACE (GFS_SOLID (solid)->s) || !GFS_SURFACE (GFS_SOLID (solid)->s)->s) {
+    gts_file_error (fp, "moving implicit surfaces are not implemented yet");
+    return;
+  }
+
+  if (!GFS_IS_SIMULATION_MOVING (gfs_object_simulation (*o))) {
+    gts_file_error (fp, "GfsSolidMoving only makes sense with GfsSimulationMoving");
+    return;
+  }
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    if (!strcmp (fp->token->str, "level")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (solid->level, gfs_object_simulation (*o), fp);
+    }
+    else {
+      gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+      return;
+    }
+  }
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void solid_moving_write (GtsObject * object, FILE * fp)
+{
+  GfsSolidMoving * solid = GFS_SOLID_MOVING (object);
+  
+  if (GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class->write) 
+      (object, fp);
+  fputs (" { level =", fp);
+  gfs_function_write (solid->level, fp);
+  fputs (" }", fp);
+}
+
+static void set_old_solid (FttCell * cell, GfsVariable * old_solid_v)
+{
+  g_free (OLD_SOLID (cell));
+  OLD_SOLID (cell) = GFS_STATE (cell)->solid;
+  GFS_STATE (cell)->solid = NULL;
+  cell->flags &= ~GFS_FLAG_PERMANENT;
+}
+
+static void check_face (FttCellFace * f, guint * nf)
+{
+  GfsSolidVector * s = GFS_STATE (f->cell)->solid;
+
+  if (s && !f->neighbor && s->s[f->d] > 0. && s->s[f->d] < 1.)
+    (*nf)++;
+}
+
+static void check_solid_fractions (GfsBox * box, guint * nf)
+{
+  FttDirection d;
+
+  gfs_cell_check_solid_fractions (box->root);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    ftt_face_traverse_boundary (box->root, d, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttFaceTraverseFunc) check_face, nf);
+}
+
+static void is_diffusion (GfsSource * s, gboolean * diffusion)
+{
+  *diffusion = (GFS_IS_SOURCE_DIFFUSION (s) != NULL);
+}
+
+static void set_permanent (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_PERMANENT;
+}
+
+typedef struct {
+  GfsDomain * domain;
+  GfsVariable * status;
+  GfsVariable ** v;
+} ReInitParams;
+
+static void redistribute_destroyed_cells_content (FttCell * cell, ReInitParams * p)
+{
+  if (GFS_VALUE (cell, p->status) != 1.)
+    return;
+
+  GfsDomain * domain = p->domain;
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (domain)->old_solid;
+  GSList * i;
+  FttCell * merged, * next;
+  gdouble s1, s2;
+  gint c;
+
+  if (!OLD_SOLID (cell) || !(merged = OLD_SOLID (cell)->merged))
+    return;
+  while (OLD_SOLID (merged) && (next = OLD_SOLID (merged)->merged))
+    merged = next;
+
+  s1 = ftt_cell_volume (cell);
+  s2 = ftt_cell_volume (merged);
+
+  /* redistribution of the velocity */
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble a = OLD_SOLID (merged) ? OLD_SOLID (merged)->a : 1.;
+    GfsVariable * var = p->v[c];
+    GFS_VALUE (merged, var) = (s1*OLD_SOLID (cell)->a*GFS_VALUE (cell, var) +
+			       s2*a*GFS_VALUE (merged, var))
+      /(s1*OLD_SOLID (cell)->a + s2*a);
+  }
+  
+  /* redistribution of tracers */
+  i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_TRACER (i->data)) {
+      gdouble a = OLD_SOLID (merged) ? OLD_SOLID (merged)->a : 1.;
+      GfsVariableTracer * t = GFS_VARIABLE_TRACER(i->data);
+      GfsVariable * var = t->advection.v;
+      GFS_VALUE (merged, var) = (s1*OLD_SOLID (cell)->a*GFS_VALUE (cell, var) +
+				 s2*a*GFS_VALUE (merged, var))
+	/(s1*OLD_SOLID (cell)->a + s2*a);
+    }
+    i = i->next;
+  }
+    
+  if (!OLD_SOLID (merged)) {
+    OLD_SOLID (merged) = g_malloc0 (sizeof (GfsSolidVector));
+    OLD_SOLID (merged)->a = 1.; 
+  }
+  OLD_SOLID (merged)->a += s1/s2*OLD_SOLID (cell)->a;
+  if (GFS_SIMULATION (domain)->advection_params.moving_order == 2)
+    redistribute_old_face (cell, merged, GFS_SIMULATION_MOVING (domain)->old_solid);
+}
+
+/**
+ * gfs_domain_reinit_solid_fractions:
+ * @domain: a #GfsDomain.
+ * @i: a list of #GfsSolids.
+ *
+ * Reinitializes the solid fractions of all the cells of @domain.
+ *
+ * If @destroy_solid is set to %TRUE, the cells entirely contained in
+ * the solid are destroyed using @cleanup as cleanup function.  
+ *
+ * Destroy the cells that are not fluid cells anymore when the solid 
+ * have moved.
+ *
+ * The fluid fractions of the destroyed is redistributed.
+ *
+ * Returns: the number of thin cells.
+ */
+static guint domain_reinit_solid_fractions (GfsSimulation * sim,
+					    GSList * i)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariable * status;
+
+  g_return_val_if_fail (sim != NULL, 0);
+
+  status = gfs_temporary_variable (domain);
+  guint thin = gfs_init_solid_fractions_leaves (domain, i, status);
+
+  if (sim->time.t != 0.) {
+    ReInitParams rp;
+    rp.domain = domain;
+    rp.status = status;
+    rp.v = gfs_domain_velocity (domain);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) redistribute_destroyed_cells_content, &rp);
+  }
+
+  gfs_init_solid_fractions_from_children (domain, TRUE,
+					  (FttCellCleanupFunc) gfs_cell_cleanup, domain, 
+					  status);
+  gts_object_destroy (GTS_OBJECT (status));
+  return thin;
+}
+
+/**
+ * reinit_solid_fractions:
+ * @sim: a #GfsSimulation.
+ *
+ * Calls the domain_reinit_solid_fractions(). Matches the
+ * boundaries by calling gfs_domain_match().
+ */
+static void reinit_solid_fractions (GfsSimulation * sim)
+{
+  guint nf = 0;
+  GfsDomain * domain = GFS_DOMAIN (sim);;
+  GSList * solids = gfs_simulation_get_solids (sim);
+  if (solids) {
+    sim->thin = domain_reinit_solid_fractions (sim, solids);
+    g_slist_free (solids);
+    gfs_domain_match (domain);
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			       (FttCellTraverseFunc) set_permanent, NULL);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim), (GtsFunc) check_solid_fractions, &nf);
+  if (nf > 0) {
+    GSList * i = domain->variables;
+    gboolean diffusion = FALSE;
+    
+    while (i && !diffusion) {
+      GfsVariable * v = i->data;
+
+      if (v->sources)
+	gts_container_foreach (v->sources, (GtsFunc) is_diffusion, &diffusion);
+      i = i->next;
+    }
+    if (diffusion)
+      g_warning ("the solid surface cuts %d boundary cells,\n"
+		 "this may cause errors for diffusion terms\n", nf);
+  }
+}
+
+/* see gfs_advection_update() for a description of what this function does */
+static void moving_advection_update (GSList * merged, const GfsAdvectionParams * par)
+{
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (par->v->domain)->old_solid;
+
+  if (merged->next == NULL) { /* cell is not merged */
+    FttCell * cell = merged->data;
+    gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+    gdouble olda = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+
+    if (GFS_IS_MIXED (cell))
+      g_assert (!gfs_cell_is_small (cell));
+
+    GFS_VALUE (cell, par->v) = (olda*GFS_VALUE (cell, par->v) + GFS_VALUE (cell, par->fv))/a;
+  }
+  else if (1 /* par->average */) {
+    /* average value */
+    GSList * i = merged;
+    gdouble w = 0., total_vol = 0.;
+
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble vol = ftt_cell_volume (cell);
+      gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+      gdouble olda = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+      
+      total_vol += vol*a;
+      w += vol*(olda*GFS_VALUE (cell, par->v) + GFS_VALUE (cell, par->fv));
+      i = i->next;
+    }
+    w /= total_vol;
+
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+      GFS_VALUE (cell, par->v) = w;
+      i = i->next;
+    }
+  }
+  else {
+    GSList * i = merged;
+    gdouble w = 0., total_vol = 0.;
+
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble vol = ftt_cell_volume (cell);
+      gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+      gdouble olda = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+
+      total_vol += vol*a;
+      if (a < GFS_SMALL) {
+	GFS_VALUE (cell, par->v) = olda*GFS_VALUE (cell, par->v)/a + 
+	  GFS_VALUE (cell, par->fv)/GFS_SMALL;
+	w += vol*GFS_VALUE (cell, par->fv)*(1. - a/GFS_SMALL);   
+      }
+      else
+	GFS_VALUE (cell, par->v) = (olda*GFS_VALUE (cell, par->v) + GFS_VALUE (cell, par->fv))/a;
+      i = i->next;
+    }
+    w /= total_vol;
+    
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+      /* fixme: small cells should be excluded here?? 
+	 (with corresponding modification in total_vol) */
+      GFS_VALUE (cell, par->v) += w;
+      i = i->next;
+    }
+  }
+}
+
+static void moving_init (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN(sim);
+  GSList * i = domain->variables;
+
+  if (sim->advection_params.moving_order == 2)
+    sim->advection_params.flux = moving_face_velocity_advection_flux;
+  else
+    sim->advection_params.flux = gfs_face_velocity_advection_flux;
+  sim->advection_params.update = (GfsMergedTraverseFunc) moving_advection_update;
+
+  while (i) {
+    if (GFS_IS_VARIABLE_TRACER_VOF (i->data))
+      g_assert_not_implemented ();
+    else if (GFS_IS_VARIABLE_TRACER (i->data)) {
+      GfsAdvectionParams * par = &GFS_VARIABLE_TRACER (i->data)->advection;
+      if (sim->advection_params.moving_order == 2)
+	par->flux = moving_face_advection_flux;
+      else
+	par->flux = gfs_face_advection_flux;
+      par->update = sim->advection_params.update;
+      par->moving_order = sim->advection_params.moving_order;
+    }
+    i = i->next;
+  }
+}
+
+static gboolean solid_moving_event (GfsEvent * event, GfsSimulation * sim)
+{
+  return (GFS_SOLID_MOVING (event)->active = 
+	  (* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_solid_moving_class ())->parent_class)->event) 
+	  (event, sim));
+}
+
+static void solid_moving_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = solid_moving_destroy;
+  GTS_OBJECT_CLASS (klass)->read = solid_moving_read;
+  GTS_OBJECT_CLASS (klass)->write = solid_moving_write;
+  klass->event = solid_moving_event;
+}
+
+static void solid_moving_init (GfsSolidMoving * solid)
+{
+  gfs_event_set (GFS_EVENT (solid),
+		 0., G_MAXDOUBLE/2., -1.,
+		 0, G_MAXINT/2, 1);
+  solid->level = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsEventClass * gfs_solid_moving_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo solid_moving_info = {
+      "GfsSolidMoving",
+      sizeof (GfsSolidMoving),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) solid_moving_class_init,
+      (GtsObjectInitFunc) solid_moving_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_solid_class ()), &solid_moving_info);
+  }
+
+  return klass;
+}
+
+/* GfsMovingRun: Object */
+
+#define MOVING_CFL 0.45
+
+static void set_dtmax (FttCell * cell, SolidInfo * p)
+{
+  gdouble size = ftt_cell_size (cell);
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble v = fabs (surface_value (cell, p->v[c], NULL));
+    if (v != 0.) {
+      gdouble dt = size*MOVING_CFL/v;
+      if (dt < p->sim->time.dtmax)
+	p->sim->time.dtmax = dt;
+    }
+  }
+}
+
+static void simulation_moving_set_timestep (GfsSimulation * sim)
+{
+  gdouble dtmax = sim->time.dtmax;
+  SolidInfo p;
+  p.sim = sim;
+  p.v = gfs_domain_velocity (GFS_DOMAIN (sim));
+  gfs_domain_traverse_mixed (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseFunc) set_dtmax, &p);
+  gfs_simulation_set_timestep (sim);
+  sim->time.dtmax = dtmax;
+}
+
+static void move_vertex (GtsPoint * p, SolidInfo * par)
+{ 
+  FttVector pos = *((FttVector *) &p->x);
+  FttCell * cell = gfs_domain_locate (GFS_DOMAIN (par->sim), pos, -2, NULL);
+  if (cell) {
+    gdouble dt = par->sim->advection_params.dt;
+    FttComponent c;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&p->x)[c] += surface_value (cell, par->v[c], &pos)*dt;
+  }
+  else
+    g_warning ("point %g,%g not in domain", pos.x, pos.y);
+}
+
+static void solid_move_remesh (GfsSolidMoving * solid, GfsSimulation * sim)
+{
+  GfsSurface * surface = GFS_SURFACE (GFS_SOLID (solid)->s);
+  if (surface->s) {
+    SolidInfo p;
+    p.sim = sim;
+    p.s = solid;
+    p.v = gfs_domain_velocity (GFS_DOMAIN (sim));
+    gts_surface_foreach_vertex (surface->s, (GtsFunc) move_vertex, &p);
+  }
+  else
+    /* implicit surface */
+    g_assert_not_implemented ();
+  remesh_surface_moving (sim, solid);
+}
+
+static void move_solids (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariable * old_solid = GFS_SIMULATION_MOVING (sim)->old_solid;
+  GfsVariable * sold2[FTT_NEIGHBORS];
+
+  gfs_domain_timer_start (domain, "move_solids");
+
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) set_old_solid, old_solid);
+
+  if (sim->advection_params.moving_order == 2) {
+    FttDirection d;
+    for (d = 0; d < FTT_NEIGHBORS; d++) {
+      sold2[d] = gfs_domain_add_variable (domain, NULL, NULL);
+      sold2[d]->coarse_fine = sold2_fine_init;
+    }
+    GFS_SIMULATION_MOVING (sim)->sold2 = sold2;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			      (FttCellTraverseFunc) set_sold2, sim);
+  }
+
+  GSList * solids = gfs_simulation_get_solids (sim), * s = solids;
+  while (s) {
+    if (GFS_IS_SOLID_MOVING (s->data) && GFS_SOLID_MOVING (s->data)->active)
+      solid_move_remesh (s->data, sim);
+    s = s->next;
+  }
+  g_slist_free (solids);
+  reinit_solid_fractions (sim);
+  gfs_domain_reshape (domain, gfs_domain_depth (domain));
+
+  if (sim->advection_params.moving_order == 2) {
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) second_order_face_fractions, sim);
+    FttDirection d;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      gts_object_destroy (GTS_OBJECT (sold2[d]));    
+    GFS_SIMULATION_MOVING (sim)->sold2 = NULL;
+  }
+
+  gfs_domain_timer_stop (domain, "move_solids");
+}
+
+static void moving_divergence_approx (FttCell * cell, DivergenceData * p)
+{
+  GFS_VALUE (cell, p->div) += 
+    GFS_STATE (cell)->solid->fv*(GFS_STATE (cell)->solid->s[2*p->c + 1] -
+				 GFS_STATE (cell)->solid->s[2*p->c])*ftt_cell_size (cell);
+}
+
+static void moving_divergence_distribution (GSList * merged, DivergenceData * p)
+{
+  if (merged->next != NULL && merged->next->data != merged->data) {
+    gdouble total_volume = 0., total_div = 0.;
+    GSList * i = merged;
+
+    while (i) {
+      FttCell * cell = i->data;
+      g_assert (FTT_CELL_IS_LEAF (cell));
+      gdouble a = GFS_STATE (cell)->solid ? GFS_STATE (cell)->solid->a : 1.;
+      total_volume += a*ftt_cell_volume (cell);
+      total_div += GFS_VALUE (cell, p->div);
+      i = i->next;
+    }
+    
+    total_div /= total_volume;
+    
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble a = GFS_STATE (cell)->solid ? GFS_STATE (cell)->solid->a : 1.;
+      GFS_VALUE (cell, p->div) = total_div*a*ftt_cell_volume (cell);
+      i = i->next;
+    }
+  }
+}
+
+static void divergence_approx_hook (GfsDomain * domain, 
+				    GfsAdvectionParams * apar, 
+				    GfsVariable * div)
+{
+  DivergenceData q;
+  GfsVariable ** v = gfs_domain_velocity (domain);
+  
+  q.div = div;
+  for (q.c = 0; q.c < FTT_DIMENSION; q.c++) {
+    gfs_domain_surface_bc (domain, v[q.c]);
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			       (FttCellTraverseFunc) moving_divergence_approx, &q);
+  }
+  gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) moving_divergence_distribution, &q);
+}
+
+static void moving_divergence_mac (FttCell * cell, DivergenceData * p)
+{
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (p->domain)->old_solid;
+  gdouble size = ftt_cell_size (cell);
+  gdouble a = GFS_STATE (cell)->solid ? GFS_STATE (cell)->solid->a : 1.;
+  gdouble olda = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+  
+  GFS_VALUE (cell, p->div) += (olda - a)*size*size/p->dt;
+}
+
+static void divergence_mac_hook (GfsDomain * domain, GfsAdvectionParams * apar, GfsVariable * div)
+{
+  DivergenceData q;
+
+  q.dt = apar->moving_order == 2 ? 2.*apar->dt : - 2.*apar->dt;
+  q.div = div;
+  q.domain = domain;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) moving_divergence_mac, &q);
+  gfs_domain_traverse_merged (domain,
+			      (GfsMergedTraverseFunc) 
+			      (apar->moving_order == 1 ?
+			       moving_divergence_distribution :
+			       moving_divergence_distribution_second_order), 
+			      &q);
+}
+
+static void moving_mac_projection (GfsSimulation * sim,
+				   GfsMultilevelParams * par,
+				   GfsAdvectionParams * apar,
+				   GfsVariable * p,
+				   GfsFunction * alpha,
+				   GfsVariable ** g)
+{
+  if (apar->moving_order == 2)
+    swap_face_fractions (sim);
+  gfs_mac_projection (GFS_DOMAIN (sim), par, apar, p, alpha, g, divergence_mac_hook);
+  if (apar->moving_order == 2)
+    swap_face_fractions_back (sim);
+}
+
+static void simulation_moving_run (GfsSimulation * sim)
+{
+  GfsVariable * p, * pmac, * res = NULL, * g[FTT_DIMENSION], * gmac[FTT_DIMENSION];
+  GfsVariable ** gc = sim->advection_params.gc ? g : NULL;
+  GfsDomain * domain;
+  GSList * i;
+
+  domain = GFS_DOMAIN (sim);
+
+  p = gfs_variable_from_name (domain->variables, "P");
+  g_assert (p);
+  pmac = gfs_variable_from_name (domain->variables, "Pmac");
+  g_assert (pmac);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gmac[c] = gfs_temporary_variable (domain);
+    if (sim->advection_params.gc)
+      g[c] = gfs_temporary_variable (domain);
+    else
+      g[c] = gmac[c];
+  }
+  gfs_variable_set_vector (gmac, FTT_DIMENSION);
+  gfs_variable_set_vector (g, FTT_DIMENSION);
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
+      res = i->data;
+    i = i->next;
+  }
+
+  moving_init (sim);
+
+  simulation_moving_set_timestep (sim);
+  if (sim->time.i == 0)
+    gfs_approximate_projection (domain,
+				&sim->approx_projection_params,
+				&sim->advection_params,
+				p, sim->physical_params.alpha, res, g,
+				divergence_approx_hook);
+  else if (sim->advection_params.gc)
+    gfs_update_gradients (domain, p, sim->physical_params.alpha, g);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    move_solids (sim);
+   
+    gfs_predicted_face_velocities (domain, FTT_DIMENSION, &sim->advection_params);
+    
+    gfs_variables_swap (p, pmac);
+
+    moving_mac_projection (sim,
+			   &sim->projection_params, 
+			   &sim->advection_params,
+			   p, sim->physical_params.alpha, gmac);
+
+    gfs_variables_swap (p, pmac);
+    
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
+   
+    gfs_centered_velocity_advection_diffusion (domain,
+					       FTT_DIMENSION,
+					       &sim->advection_params,
+					       gmac,
+					       sim->time.i > 0 || !gc ? gc : gmac,
+					       sim->physical_params.alpha);
+        
+    gfs_advance_tracers (domain, sim->advection_params.dt);
+
+    if (gc) {
+      gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, sim->time.i > 0 ? gc : gmac, 
+				       -sim->advection_params.dt);
+    }
+    else if (gfs_has_source_coriolis (domain)) {
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, sim->advection_params.dt);
+      gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, -sim->advection_params.dt);
+    }
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    gfs_approximate_projection (domain,
+				&sim->approx_projection_params, 
+				&sim->advection_params, p, sim->physical_params.alpha, res, g,
+				divergence_approx_hook);
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    simulation_moving_set_timestep (sim);
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gts_object_destroy (GTS_OBJECT (gmac[c]));
+    if (sim->advection_params.gc)
+      gts_object_destroy (GTS_OBJECT (g[c]));
+  }
+}
+
+static void simulation_moving_class_init (GfsSimulationClass * klass)
+{
+  klass->run = simulation_moving_run;
+}
+
+static void old_solid_cleanup (FttCell * cell, GfsVariable * old_solid_v)
+{
+  g_free (OLD_SOLID (cell));
+  OLD_SOLID (cell) = NULL;
+}
+
+static void none (void) {}
+
+static void simulation_moving_init (GfsDomain * domain)
+{
+  gfs_domain_add_variable (domain, "div", "Divergence")->centered = TRUE;
+
+  /* old_solid will hold a pointer to a GfsSolidVector */
+  GfsVariable * old_solid = gfs_domain_add_variable (domain, NULL, NULL); 
+  GFS_SIMULATION_MOVING (domain)->old_solid = old_solid;
+  /* pointers need to be "interpolated" correctly (i.e. not at all) */
+  old_solid->coarse_fine = (GfsVariableFineCoarseFunc) none;
+  old_solid->fine_coarse = (GfsVariableFineCoarseFunc) none;
+  /* the memory needs to be freed when the cell is cleaned up */
+  old_solid->cleanup = (FttCellCleanupFunc) old_solid_cleanup;
+  /* switch off boundary conditions */
+  GfsBc * bc = gfs_bc_new (gfs_bc_class (), old_solid, FALSE);
+  bc->bc = bc->homogeneous_bc = bc->face_bc = (FttFaceTraverseFunc) none;
+  gfs_variable_set_default_bc (old_solid, bc);
+}
+
+GfsSimulationClass * gfs_simulation_moving_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_simulation_moving_info = {
+      "GfsSimulationMoving",
+      sizeof (GfsSimulationMoving),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) simulation_moving_class_init,
+      (GtsObjectInitFunc) simulation_moving_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), 
+				  &gfs_simulation_moving_info);
+  }
+
+  return klass;
+}
diff --git a/src/moving.h b/src/moving.h
new file mode 100644
index 0000000..7ec87ce
--- /dev/null
+++ b/src/moving.h
@@ -0,0 +1,76 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __MOVING_H__
+#define __MOVING_H__
+
+#include <gts.h>
+#include "variable.h"
+#include "utils.h"
+#include "solid.h"
+#include "advection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GfsSolidMoving         GfsSolidMoving;
+
+struct _GfsSolidMoving {
+  /*< private >*/
+  GfsSolid parent;
+
+  /*< public >*/
+  GfsFunction * level;
+  gboolean active;
+};
+
+GfsEventClass * gfs_solid_moving_class (void);
+
+#define GFS_SOLID_MOVING(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSolidMoving,\
+					         gfs_solid_moving_class ())
+#define GFS_IS_SOLID_MOVING(obj)         (gts_object_is_from_class (obj,\
+						 gfs_solid_moving_class ()))
+
+/* GfsSimulationMoving: Header */
+
+typedef struct _GfsSimulationMoving         GfsSimulationMoving;
+
+struct _GfsSimulationMoving {
+  /*< private >*/
+  GfsSimulation parent;
+
+  /*< public >*/
+  GfsVariable * old_solid, ** sold2;
+};
+
+#define GFS_SIMULATION_MOVING(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSimulationMoving,\
+					         gfs_simulation_moving_class ())
+#define GFS_IS_SIMULATION_MOVING(obj)         (gts_object_is_from_class (obj,\
+						 gfs_simulation_moving_class ()))
+
+GfsSimulationClass * gfs_simulation_moving_class            (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MOVING_H__ */
diff --git a/src/moving2.c b/src/moving2.c
new file mode 100644
index 0000000..0417fa4
--- /dev/null
+++ b/src/moving2.c
@@ -0,0 +1,805 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2005-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+/*
+ * Code only used by second-order moving solid boundaries
+ */
+
+#define SOLD2(c, d)  (GFS_VALUE (c, sold2[d]))
+
+static void sold2_fine_init (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  guint n;
+
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++)
+    if (child.c[n])
+      GFS_VALUE (child.c[n], v) = 1.;
+}
+
+static int cell_is_corner (FttCell * cell)
+{
+  FttDirection d, d1, d2;
+  gdouble  norm;
+  FttCellNeighbors neighbors;
+  FttVector n1, n2;
+
+
+  g_assert (cell);
+
+  ftt_cell_neighbors (cell,&neighbors);
+
+  d1 = d2 = -1;
+
+  if (!GFS_IS_MIXED(cell))
+    return 0;
+
+  for (d = 0; d < FTT_NEIGHBORS; d ++)
+    if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0. && d1 == -1 && d2 == -1)
+      d1 = d;
+    else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0 && d2 == -1)
+      d2 = d;
+    else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0.)
+      g_assert_not_reached ();
+
+  if ( d1 == -1 || d2 == -1) {
+    FttVector pos;
+    ftt_cell_pos (cell,&pos);
+    
+    g_warning ("REA: %f, %f \n", pos.x, pos.y);
+    g_warning ("d1: %i d2: %i  \n", d1,d2);
+    
+    g_assert_not_reached ();
+  }
+
+ 
+
+
+  gfs_solid_normal (neighbors.c[d1], &n1);
+  norm = sqrt (n1.x*n1.x + n1.y*n1.y);
+  if (norm != 0.) {
+    n1.x /= norm;
+    n1.y /= norm;
+  }
+  gfs_solid_normal (neighbors.c[d2], &n2);
+  norm = sqrt (n2.x*n2.x + n2.y*n2.y);
+  if (norm != 0.) {
+    n2.x /= norm;
+    n2.y /= norm;
+  }
+
+  if (d1/2 == d2/2)
+    return 0;
+  else {
+    if (neighbors.c[d2])
+      if ( neighbors.c[d1])
+	if (GFS_IS_MIXED (neighbors.c[d2]) && GFS_IS_MIXED (neighbors.c[d1]))
+	  if (fabs(n1.x*n2.x+n1.y*n2.y) < 0.70) {
+	    if (GFS_STATE(neighbors.c[d1])->solid->s[d1] > 0 && GFS_STATE(neighbors.c[d1])->solid->s[d1] < 1)
+	      return 1;
+	    if (GFS_STATE(neighbors.c[d2])->solid->s[d2] > 0 && GFS_STATE(neighbors.c[d2])->solid->s[d2] < 1)
+	      return 1;
+	  }
+    return 0;
+  }
+}
+
+static int cell_was_corner (FttCell * cell, GfsVariable * old_solid_v, GfsVariable ** sold2)
+{
+  FttDirection d, d1, d2;
+  
+  g_assert (cell);
+
+  d1 = d2 = -1;
+
+  if (!OLD_SOLID (cell))
+    return 0;
+
+  for (d = 0; d < FTT_NEIGHBORS; d ++)
+    if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0. && d1 == -1 && d2 == -1)
+      d1 = d;
+    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0 && d2 == -1)
+      d2 = d;
+    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0.)
+      g_assert_not_reached (); 
+
+  if (d1/2 == d2/2)
+    return 0;
+  else {
+    FttCellNeighbors neighbors;
+
+    ftt_cell_neighbors (cell, &neighbors);
+
+    if (neighbors.c[d1] && neighbors.c[d2]) {
+      FttVector n1, n2;
+      FttComponent c;
+      gdouble norm;
+
+      for (c = 0; c < FTT_DIMENSION; c++) {
+	(&n1.x)[c] = (SOLD2 (neighbors.c[d1], 2*c + 1) - SOLD2 (neighbors.c[d1], 2*c));
+	(&n2.x)[c] = (SOLD2 (neighbors.c[d2], 2*c + 1) - SOLD2 (neighbors.c[d2], 2*c));
+      }
+      norm = sqrt (n1.x*n1.x + n1.y*n1.y);
+      if (norm != 0.) {
+	n1.x /= norm;
+	n1.y /= norm;
+      }
+      norm = sqrt (n2.x*n2.x + n2.y*n2.y);
+      if (norm != 0.) {
+	n2.x /= norm;
+	n2.y /= norm;
+      }    
+      if (fabs(n1.x*n2.x+n1.y*n2.y) < 0.70) {
+	if (SOLD2 (neighbors.c[d1], d1) > 0 && SOLD2 (neighbors.c[d1], d1) < 1)
+	  return 1.;
+	else if (SOLD2 (neighbors.c[d2], d2) > 0 && SOLD2 (neighbors.c[d2], d2) < 1)
+	  return 1;
+      }
+    }
+    return 0;
+  }
+}
+
+static double new_fluid_old_solid (FttCell * cell, FttDirection d1, 
+				   GfsVariable * old_solid,
+				   GfsVariable ** sold2) 
+{  
+  FttDirection d;
+  FttCellNeighbors neighbors;
+  double s1, s2;
+
+  g_assert(cell);
+
+  s1 = 1.-SOLD2 (cell, d1);
+  ftt_cell_neighbors (cell,&neighbors);
+  for  (d = 0; d < 2*FTT_DIMENSION;d++)
+    if (d != 2*(d1/2) && d != 2*(d1/2)+1)
+      if (neighbors.c[d])
+	if(GFS_IS_MIXED(neighbors.c[d]))
+	  if (!cell_is_corner (neighbors.c[d]) && 
+	      !cell_was_corner (neighbors.c[d], old_solid, sold2)) {
+	    if (GFS_STATE(neighbors.c[d])->solid->s[d1] != 1.) {
+	      if (SOLD2 (neighbors.c[d], d1) == 0.)
+		{
+		  s2 = GFS_STATE(neighbors.c[d])->solid->s[d1];
+		  return s2/(s1+s2);
+		}		  
+	    }
+	  } 
+  return -1.;
+}
+
+static double new_solid_old_fluid (FttCell * cell, FttDirection d1, 
+				   GfsVariable * old_solid,
+				   GfsVariable ** sold2) 
+{  
+  FttDirection d;
+  FttCellNeighbors neighbors;
+  double s1, s2;
+
+  g_assert(cell);
+
+  s1 = 1.-GFS_STATE (cell)->solid->s[d1];
+		    
+  ftt_cell_neighbors (cell,&neighbors);
+  for  (d = 0; d < 2*FTT_DIMENSION;d++)
+    if (d != 2*(d1/2) && d != 2*(d1/2)+1)
+      if (neighbors.c[d])
+	if (!cell_is_corner(neighbors.c[d]) && 
+	    !cell_was_corner(neighbors.c[d], old_solid, sold2))
+	  if (GFS_STATE(neighbors.c[d])->solid)	 
+	    if (GFS_STATE(neighbors.c[d])->solid->s[d1] == 0. && SOLD2 (neighbors.c[d], d1) != 1.) {
+	      
+	      s2 = SOLD2 (neighbors.c[d], d1);
+	      return s1/(s1+s2);
+	    }
+  return -1.;
+}
+
+static double new_solid_old_solid (FttCell * cell, FttDirection d1,
+				   GfsVariable * old_solid,
+				   GfsVariable ** sold2)
+{
+  FttDirection d;
+  FttCellNeighbors neighbors;
+  double s1, s2;
+
+  g_assert(cell);
+
+  s1 = GFS_STATE (cell)->solid->s[d1];
+  ftt_cell_neighbors (cell,&neighbors);
+  for  (d = 0; d < 2*FTT_DIMENSION;d++)
+    if (d != 2*(d1/2) && d != 2*(d1/2)+1)
+      if (neighbors.c[d] &&
+	  !cell_is_corner(neighbors.c[d]) && 
+	  !cell_was_corner(neighbors.c[d], old_solid, sold2)) {
+	if ((GFS_IS_MIXED(neighbors.c[d]) && GFS_STATE(neighbors.c[d])->solid->s[d1] == 1.) ||
+	    !GFS_IS_MIXED(neighbors.c[d])) {
+	  if (SOLD2 (neighbors.c[d], d1) != 1.){
+	    s2 = 1.-SOLD2 (neighbors.c[d], d1);
+	    return s1/(s1+s2);
+	  }
+	}
+	else if ((GFS_STATE(cell)->solid->s[d1] == 0. && GFS_IS_MIXED(neighbors.c[d])) ) {
+	  s1 = SOLD2 (cell, d1);
+	  s2 = 1.-GFS_STATE(neighbors.c[d])->solid->s[d1];
+	  return s2/(s1+s2);
+	}
+      }
+  return -1.;
+}
+
+static void second_order_face_fractions (FttCell * cell, GfsSimulationMoving * sim)
+{
+#ifndef FTT_2D /* 3D */
+  g_assert_not_implemented ();
+#endif
+
+  GfsVariable * old_solid_v = sim->old_solid;
+  GfsVariable ** sold2 = sim->sold2;
+  gdouble dt1, dt2, dto1, dto2, s1, s2;
+  gint d1, d2, d, do1, do2;
+  FttCellNeighbors neighbors;
+
+  dt1 = dt2 = dto1 = dto2 = -2;
+  d1 = d2 = do1 = do2 = -1;
+  s1 = s2 = -1;
+
+  g_assert(cell);
+      
+  ftt_cell_neighbors (cell,&neighbors);
+
+  if (!OLD_SOLID (cell) && !GFS_IS_MIXED(cell))
+    return;
+
+  if (!OLD_SOLID (cell)) {
+    FttDirection c;
+    OLD_SOLID (cell) = g_malloc0 (sizeof (GfsSolidVector));
+
+    OLD_SOLID (cell)->a = 1.;
+    for (c = 0; c < FTT_NEIGHBORS; c++)
+      OLD_SOLID (cell)->s[c] = 1.;
+  }
+
+  /* Find directions of intersection */
+  if (GFS_IS_MIXED(cell))
+    for (d = 0; d < FTT_NEIGHBORS; d ++) {
+      if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0. &&
+	  d1 == -1 && d2 == -1)
+	d1 = d;
+      else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0 && d2 == -1)
+	d2 = d;
+      else if (GFS_STATE(cell)->solid->s[d] != 1. && GFS_STATE(cell)->solid->s[d] != 0.)
+	g_assert_not_reached (); 
+    }
+  
+  for (d = 0; d < FTT_NEIGHBORS; d ++) {
+    if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0. && do1 == -1 && do2 == -1)
+      do1 = d;
+    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0 && do2 == -1)
+      do2 = d;
+    else if (SOLD2 (cell, d) != 1. && SOLD2 (cell, d) != 0.)
+      g_assert_not_reached (); 
+  }
+
+  /* Treats easy cases */
+  if (d1 != -1 && d1 == do1)
+    OLD_SOLID (cell)->s[d1] = SOLD2 (cell, d1);
+  if (d2 != -1 && d2 == do2)
+    OLD_SOLID (cell)->s[d2] = SOLD2 (cell, d2);
+
+  if (d1 == do1 && d2 == do2)
+    return;
+    
+  /* Finds timescale for d1/do1 */
+  if (d1 != -1) {
+    if (SOLD2 (cell, d1) == 1.) {
+      dt1 = new_solid_old_fluid (cell, d1, old_solid_v, sold2);
+      if (dt1 == -1)
+	if (neighbors.c[d1]){
+	  FttDirection dop = ftt_opposite_direction[d1];
+	  dt1 = new_solid_old_fluid (neighbors.c[d1], dop, old_solid_v, sold2);
+	}
+    }   
+    else if (SOLD2 (cell, d1) == 0.){
+      dt1 = new_solid_old_solid (cell, d1, old_solid_v, sold2);
+    }  
+  }
+  
+  if (do1 != -1 && do1 != d1 && do1 != d2) {
+    if (GFS_IS_MIXED(cell) && GFS_STATE(cell)->solid->s[do1] == 0.)
+      dto1 = new_solid_old_solid (cell, do1, old_solid_v, sold2);
+    else
+      dto1 = new_fluid_old_solid (cell, do1, old_solid_v, sold2);
+  }
+
+  /* Finds timescale for d2/do2 */
+
+  if (d2 != -1) {
+    if (SOLD2 (cell, d2) == 1.) {
+      dt2 = new_solid_old_fluid (cell, d2, old_solid_v, sold2);
+      if (dt2 == -1 && neighbors.c[d2]) {
+	FttDirection dop = ftt_opposite_direction[d2];
+	dt2 = new_solid_old_fluid (neighbors.c[d2], dop, old_solid_v, sold2);
+      }
+    }
+    else if (SOLD2 (cell, d2) == 0.)
+      dt2 = new_solid_old_solid (cell, d2, old_solid_v, sold2);
+  }
+ 
+  if (do2 != -1 && do2 != d1 && do2 != d2) {
+    if (GFS_IS_MIXED(cell) && GFS_STATE(cell)->solid->s[do2] == 0.)
+      dto2 = new_solid_old_solid (cell, do2, old_solid_v, sold2);
+    else
+      dto2 = new_fluid_old_solid (cell, do2, old_solid_v, sold2);
+  }
+ 
+  /* Uses time-scale from other faces if one is missing */
+  if (dt1 == -1) {
+    if (dto1 != -2)
+      dt1 = dto1;
+    else if (dt2 != -2)
+      dt1 = dt2;
+    else if (dto2 != -2)
+      dt1 = dto2;
+  }
+
+  if (dt2 == -1) {
+    if (dt1 != -2)
+      dt2 = dt1;
+    else if (dto2 != -2)
+      dt2 = dto2;
+    else if (dto1 != -2)
+      dt2 = dto1;
+  }
+
+  if (dto1 == -1) {
+    if (dt1 != -2)
+      dto1 = dt1;
+    else if (dt2 != -2)
+      dto1 = dt2;
+    else if (dto2 != -2)
+      dto1 = dto2;
+  }
+
+  if (dto2 == -1) {
+    if (dt1 != -2)
+      dto2 = dt1;
+    else if (dt2 != -2)
+      dto2 = dt2;
+    else if (dto1 != -2)
+      dto2 = dto1;
+  }
+
+  /* Treats cell is corner */
+  if (dt1 != -2 && dt2 != -2) {
+    if (dt1 != dt2 && d1/2 != d2/2) {
+      if (cell_is_corner (cell)) {
+	if (dt1 < dt2)
+	  dt2 = dt1;
+	else
+	  dt1 = dt2;
+      }}}
+
+  /* Treats cell was corner */
+  if (dto1 != -2 && dto2 != -2 && 
+      dto1 != dto2 && do1/2 != do2/2 &&
+      cell_was_corner (cell, old_solid_v, sold2)) {
+    if (dto1 < dto2)
+      dto2 = dto1;
+    else
+      dto1 = dto2;
+  }
+  
+  /* Compute the t^n+1/2 contribution of the face */
+  if (do1 > -1)
+    if (do1 != d1 && do1 != d2) {
+      OLD_SOLID (cell)->s[do1]=SOLD2 (cell, do1)*(1-dto1)+dto1;
+      if (neighbors.c[do1])
+	if (!OLD_SOLID (neighbors.c[do1]) || !GFS_IS_MIXED(neighbors.c[do1])) {
+	  if (!OLD_SOLID (neighbors.c[do1])) {
+	    FttDirection c;
+	    OLD_SOLID (neighbors.c[do1]) = g_malloc0 (sizeof (GfsSolidVector));
+	    OLD_SOLID (neighbors.c[do1])->a = 1.;
+	    for (c = 0; c < FTT_NEIGHBORS; c++)
+	      OLD_SOLID (neighbors.c[do1])->s[c] = 1.;
+	  }	  
+	  OLD_SOLID (neighbors.c[do1])->s[ftt_opposite_direction[do1]] = 
+	    SOLD2 (cell, do1)*(1-dto1)+dto1;
+	}
+    }
+
+  if (do2 > -1)
+    if (do2 != d1 && do2 != d2) {
+      OLD_SOLID (cell)->s[do2]=SOLD2 (cell, do2)*(1-dto2)+dto2;
+      if (neighbors.c[do2])
+	if (!OLD_SOLID (neighbors.c[do2]) || !GFS_IS_MIXED(neighbors.c[do2])) {
+	  if (!OLD_SOLID (neighbors.c[do2])) {
+	    FttDirection c;
+	    OLD_SOLID (neighbors.c[do2]) = g_malloc0 (sizeof (GfsSolidVector));
+	    OLD_SOLID (neighbors.c[do2])->a = 1.;
+	    for (c = 0; c < FTT_NEIGHBORS; c++)
+	      OLD_SOLID (neighbors.c[do2])->s[c] = 1.;
+	  }	  
+	  OLD_SOLID (neighbors.c[do2])->s[ftt_opposite_direction[do2]] = 
+	    SOLD2 (cell, do2)*(1-dto2)+dto2;
+	}
+    }
+
+
+  if (d1 > -1) {
+    if (SOLD2 (cell, d1) == 0.)
+      OLD_SOLID (cell)->s[d1] = GFS_STATE(cell)->solid->s[d1]*(dt1-1.); 
+    else if (SOLD2 (cell, d1) == 1.)
+      OLD_SOLID (cell)->s[d1] = (dt1-1.)*GFS_STATE(cell)->solid->s[d1]+2.-dt1;
+  }
+
+  if (d2 > -1) {
+    if (SOLD2 (cell, d2) == 0.)
+      OLD_SOLID (cell)->s[d2] = GFS_STATE(cell)->solid->s[d2]*(dt2-1.); 
+    else if (SOLD2 (cell, d2) == 1.)
+      OLD_SOLID (cell)->s[d2] = (dt2-1.)*GFS_STATE(cell)->solid->s[d2]+2.-dt2;
+  }
+
+  if (d1/2 == d2/2 && do1 == -1 && do2 == -1)  /* third face has to be treated for 
+						  the timescale determined on the other faces */  
+    for (d = 0; d < FTT_NEIGHBORS; d ++)
+      if (d/2 != d1/2 && SOLD2 (cell, d) == 0.)
+	OLD_SOLID (cell)->s[d] = -1.+dt1+dt2;
+    
+
+  if (do1/2 == do2/2 && d1 == -1 && d2 == -1)
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (d/2 != do1/2 && SOLD2 (cell, d) == 0.)
+	OLD_SOLID (cell)->s[d] = -1.+dto1+dto2;
+}
+
+static void set_sold2 (FttCell * cell, GfsSimulationMoving * sim)
+{
+  GfsVariable * old_solid_v = sim->old_solid;
+  GfsVariable ** sold2 = sim->sold2;
+  FttDirection d;
+
+  if (OLD_SOLID (cell))
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      SOLD2 (cell, d) = OLD_SOLID (cell)->s[d];
+  else
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      SOLD2 (cell, d) = 1.;
+}
+
+static void redistribute_old_face_in_merged (FttCell * cell, 
+					     FttCell * merged, FttDirection d, 
+					     GfsVariable * old_solid_v)
+{  
+  gint i;
+  gdouble sc, sm;
+  
+  g_assert (cell != NULL);
+  g_assert (merged != NULL);
+
+  sc = ftt_cell_volume(cell);
+  sm = ftt_cell_volume(merged);
+  
+  if (sc != sm)
+    printf("Face redistribution not implemented yet for adaptive grid \n");
+  g_assert (sc == sm);
+  
+  for (i = 0; i < FTT_DIMENSION;i++)
+    if (i != d/2) {
+      FttCellNeighbors neighbors;
+      FttVector pos;
+      
+      ftt_cell_pos(cell,&pos);
+      ftt_cell_neighbors (merged,&neighbors);
+
+      GfsSolidVector * old_solid_merged = OLD_SOLID (merged);
+      if (!old_solid_merged) {
+	FttDirection c;
+	OLD_SOLID (merged) = old_solid_merged = g_malloc0 (sizeof (GfsSolidVector));
+	old_solid_merged->a = 1.;
+	for (c = 0; c < FTT_NEIGHBORS; c++)
+	  old_solid_merged->s[c] = 1.;
+      }
+          
+      old_solid_merged->s[2*i] += OLD_SOLID (cell)->s[2*i];
+
+      if (neighbors.c[2*i]) {
+	GfsSolidVector * old_solid = OLD_SOLID (neighbors.c[2*i]);
+	if (!old_solid) {
+	  FttDirection c;
+	  OLD_SOLID (neighbors.c[2*i]) = old_solid = g_malloc0 (sizeof (GfsSolidVector));
+	  old_solid->a = 1.;
+	  for (c = 0; c < FTT_NEIGHBORS; c++)
+	    old_solid->s[c] = 1.;
+	}
+	old_solid->s[ftt_opposite_direction[2*i]] += OLD_SOLID (cell)->s[2*i];
+      }
+      
+      old_solid_merged->s[2*i+1] += OLD_SOLID (cell)->s[2*i+1];
+      
+      if (neighbors.c[2*i+1]) {
+	GfsSolidVector * old_solid = OLD_SOLID (neighbors.c[2*i+1]);
+	if (!old_solid) {
+	  FttDirection c;
+	  OLD_SOLID (neighbors.c[2*i+1]) = old_solid = g_malloc0 (sizeof (GfsSolidVector));
+	  old_solid->a = 1.;
+	  for (c = 0; c < FTT_NEIGHBORS; c++)
+	    old_solid->s[c] = 1.;
+	}
+	old_solid->s[ftt_opposite_direction[2*i+1]] += OLD_SOLID (cell)->s[2*i+1];	
+      }
+    }
+}
+
+static void redistribute_old_face (FttCell * cell, FttCell * merged, GfsVariable * old_solid) 
+{
+  FttCellNeighbors neighbors;
+  FttDirection d;
+
+  ftt_cell_neighbors (cell,&neighbors);
+  for (d = 0; d< FTT_NEIGHBORS; d++)
+    if (neighbors.c[d])
+      redistribute_old_face_in_merged (cell, neighbors.c[d], d, old_solid);
+}
+
+static double face_fraction_half (const FttCellFace * face, const GfsAdvectionParams * par)
+{
+  GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (par->v->domain)->old_solid;
+  if (face->cell && OLD_SOLID (face->cell))
+    return OLD_SOLID (face->cell)->s[face->d];
+  return 1.;
+}
+
+/* see gfs_face_advection_flux() for the initial implementation with static boundaries */
+static void moving_face_advection_flux (const FttCellFace * face,
+					const GfsAdvectionParams * par)
+{
+  gdouble flux;
+  
+  /* fixme: what's up with face mapping? */
+  flux = face_fraction_half (face, par)*GFS_FACE_NORMAL_VELOCITY (face)*par->dt*
+    gfs_face_upwinded_value (face, GFS_FACE_UPWINDING, NULL)/ftt_cell_size (face->cell);
+  if (!FTT_FACE_DIRECT (face))
+    flux = - flux;
+  GFS_VARIABLE (face->cell, par->fv->i) -= flux;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_VARIABLE (face->neighbor, par->fv->i) += flux;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_VARIABLE (face->neighbor, par->fv->i) += flux/FTT_CELLS;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/* see gfs_face_velocity_advection_flux() for the initial implementation with static boundaries */
+static void moving_face_velocity_advection_flux (const FttCellFace * face,
+						 const GfsAdvectionParams * par)
+{
+  gdouble flux;
+  FttComponent c = par->v->component;
+
+  g_return_if_fail (c >= 0 && c < FTT_DIMENSION);
+
+  /* fixme: what's up with face mapping? */
+  flux = face_fraction_half (face, par)*GFS_FACE_NORMAL_VELOCITY (face)*
+    par->dt/ftt_cell_size (face->cell);
+#if 0
+  if (c == face->d/2) /* normal component */
+    flux *= GFS_FACE_NORMAL_VELOCITY (face);
+  else /* tangential component */
+#else
+    flux *= gfs_face_upwinded_value (face, par->upwinding, par->u)
+      /* pressure correction */
+      - gfs_face_interpolated_value (face, par->g[c]->i)*par->dt/2.;
+#endif
+  if (!FTT_FACE_DIRECT (face))
+    flux = - flux;
+  GFS_VARIABLE (face->cell, par->fv->i) -= flux;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_VARIABLE (face->neighbor, par->fv->i) += flux;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_VARIABLE (face->neighbor, par->fv->i) += flux/FTT_CELLS;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void swap_fractions (FttCell * cell, GfsVariable * old_solid_v) {
+  FttDirection c;
+  
+  g_assert (cell);
+  
+  if (FTT_CELL_IS_LEAF(cell)) {
+    if (OLD_SOLID (cell)) {
+      GfsSolidVector * solid_old = OLD_SOLID (cell);
+      
+      if (GFS_STATE (cell)->solid) {
+	GfsSolidVector * solid = GFS_STATE (cell)->solid;
+	
+	OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged;
+	
+	for (c = 0; c < 2*FTT_DIMENSION; c++) 
+	  if (solid->s[c] == 0.)
+	    solid_old->s[c] = 0;
+	  else
+	    solid_old->s[c] = (solid_old->s[c]+solid->s[c])/2. ;	
+      }
+      else {
+	OLD_SOLID (cell)->merged = NULL;
+	
+	for (c = 0; c < 2*FTT_DIMENSION; c++)
+	  solid_old->s[c] = (solid_old->s[c]+1.)/2. ;
+	
+      }
+    }
+    else if (GFS_STATE (cell)->solid) {
+      GfsSolidVector * solid = GFS_STATE (cell)->solid;
+      GfsSolidVector * solid_old = OLD_SOLID (cell) = g_malloc0 (sizeof (GfsSolidVector));
+      OLD_SOLID (cell)->a= 1.;
+      OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged;
+      
+      for (c = 0; c < 2*FTT_DIMENSION; c++) 
+	solid_old->s[c] = 1.;	
+      
+      for (c = 0; c < 2*FTT_DIMENSION; c++) 
+	if (solid->s[c] == 0.)
+	  solid_old->s[c] = 0;
+	else
+	  solid_old->s[c] = (solid_old->s[c]+solid->s[c])/2. ;
+    }
+  }
+  
+  if (OLD_SOLID (cell)) {
+    if (GFS_STATE(cell)->solid) {
+      GfsSolidVector * tmp = OLD_SOLID (cell);
+      OLD_SOLID (cell)->merged = GFS_STATE (cell)->solid->merged;
+      OLD_SOLID (cell) = GFS_STATE(cell)->solid;
+      GFS_STATE(cell)->solid = tmp;
+      tmp = NULL;
+    }
+    else {
+      OLD_SOLID (cell)->merged = NULL;
+      GFS_STATE(cell)->solid = OLD_SOLID (cell);
+      OLD_SOLID (cell) = NULL;
+    }
+  }
+  else if (GFS_STATE(cell)->solid) {
+    OLD_SOLID (cell) = GFS_STATE(cell)->solid;
+    GFS_STATE(cell)->solid = NULL;
+  }
+  
+  
+  /* Check for negative fractions and fix */
+  if (GFS_STATE(cell)->solid)
+    for (c = 0; c < 2*FTT_DIMENSION; c++)
+      if (GFS_STATE(cell)->solid->s[c] < 0.) {
+	if (OLD_SOLID (cell)) 
+	  if (OLD_SOLID (cell)->s[c] >= 0.)
+	    GFS_STATE(cell)->solid->s[c] = OLD_SOLID (cell)->s[c];
+	  else
+	    GFS_STATE(cell)->solid->s[c] = 1.;
+	else
+	  GFS_STATE(cell)->solid->s[c] = 0.;
+      }
+  
+  if (OLD_SOLID (cell)) 
+    for (c = 0; c < 2*FTT_DIMENSION; c++)
+      if (OLD_SOLID (cell)->s[c] < 0.){
+	if (GFS_STATE(cell)->solid)
+	  if (GFS_STATE(cell)->solid->s[c] >= 0.)
+	    OLD_SOLID (cell)->s[c] = GFS_STATE(cell)->solid->s[c];
+	  else
+	    OLD_SOLID (cell)->s[c] = 1.;
+	else
+	  OLD_SOLID (cell)->s[c] = 0.;
+      }
+}
+
+static void old_solid_fractions_from_children (FttCell * cell)
+{
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren child;
+    guint i;
+    
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i])
+	old_solid_fractions_from_children (child.c[i]);
+    
+      gfs_cell_init_solid_fractions_from_children (cell);
+  }
+}
+
+static void foreach_box (GfsBox * box, gpointer data)
+{
+  old_solid_fractions_from_children (box->root);
+}
+
+static void swap_face_fractions (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) swap_fractions, 
+			    GFS_SIMULATION_MOVING (sim)->old_solid);
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) foreach_box, NULL);
+}
+
+static void swap_fractions_back (FttCell * cell, GfsVariable * old_solid_v) 
+{
+  if (OLD_SOLID (cell))
+    if (GFS_STATE(cell)->solid) {
+      GfsSolidVector * tmp = OLD_SOLID (cell);
+      OLD_SOLID (cell) = GFS_STATE(cell)->solid;
+      GFS_STATE(cell)->solid = tmp;
+      tmp = NULL;
+    }
+    else {
+      GFS_STATE(cell)->solid = OLD_SOLID (cell);
+      OLD_SOLID (cell) = NULL;
+    }
+  else
+    if (GFS_STATE(cell)->solid) {
+      OLD_SOLID (cell) = GFS_STATE(cell)->solid;
+      GFS_STATE(cell)->solid = NULL;
+    }
+}
+
+static void swap_face_fractions_back (GfsSimulation * sim) 
+{
+  gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) swap_fractions_back,
+			    GFS_SIMULATION_MOVING (sim)->old_solid);
+}
+
+static void moving_divergence_distribution_second_order (GSList * merged, DivergenceData * p)
+{
+  if (merged->next != NULL && merged->next->data != merged->data) {
+    gdouble total_volume = 0., total_div = 0.;
+    GfsVariable * old_solid_v = GFS_SIMULATION_MOVING (p->domain)->old_solid;
+    GSList * i = merged;
+
+    while (i) {
+      FttCell * cell = i->data;
+      g_assert (FTT_CELL_IS_LEAF (cell));
+      gdouble a = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+      total_volume += a*ftt_cell_volume (cell);
+      total_div += GFS_VALUE (cell, p->div);
+      i = i->next;
+    }
+    total_div /= total_volume;
+
+    i = merged;
+    while (i) {
+      FttCell * cell = i->data;
+      gdouble a = OLD_SOLID (cell) ? OLD_SOLID (cell)->a : 1.;
+      GFS_VALUE (cell, p->div) = total_div*a*ftt_cell_volume (cell);
+      i = i->next;
+    }
+  }
+}
diff --git a/src/mpi_boundary.c b/src/mpi_boundary.c
new file mode 100644
index 0000000..2deefd1
--- /dev/null
+++ b/src/mpi_boundary.c
@@ -0,0 +1,303 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "domain.h"
+#include "mpi_boundary.h"
+#include "adaptive.h"
+
+static void boundary_mpi_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_boundary_mpi_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %d %d", GFS_BOUNDARY_MPI (o)->process, GFS_BOUNDARY_MPI (o)->id);
+}
+
+static void boundary_mpi_read (GtsObject ** o, GtsFile * fp)
+{
+  if (fp->type == GTS_INT) {
+    GFS_BOUNDARY_MPI (*o)->process = atoi (fp->token->str);
+    gts_file_next_token (fp);
+    if (fp->type != GTS_INT) {
+      gts_file_error (fp, "expecting an integer (id)");
+      return;
+    }
+    GFS_BOUNDARY_MPI (*o)->id = atoi (fp->token->str);
+    gts_file_next_token (fp);
+  }
+  else
+    GFS_BOUNDARY_MPI (*o)->process = GFS_BOUNDARY_MPI (*o)->id = -1;
+}
+
+#ifdef HAVE_MPI
+
+/* #define DEBUG mpi_debug */
+
+static guint tag_shift = 32767/FTT_NEIGHBORS;
+
+#define TAG(boundary)           (tag_shift*(boundary)->d + (boundary)->box->id)
+#define MATCHING_TAG(boundary)  (tag_shift*FTT_OPPOSITE_DIRECTION ((boundary)->d) +\
+                                 GFS_BOUNDARY_MPI (boundary)->id)
+
+#ifdef DEBUG
+FILE * mpi_debug = NULL;
+#endif
+
+static void send (GfsBoundary * bb)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+  GfsBoundaryMpi * mpi = GFS_BOUNDARY_MPI (bb);
+  GfsDomain * domain = gfs_box_domain (bb->box);
+
+  if (domain->pid < 0)
+    return;
+
+  g_assert (boundary->sndcount <= boundary->sndbuf->len);
+  if (GFS_BOUNDARY (boundary)->type == GFS_BOUNDARY_MATCH_VARIABLE) {
+#ifdef DEBUG
+fprintf (DEBUG, "%d send to %d with tag %d match variable size\n",
+	 domain->pid, 
+	 mpi->process,
+	 TAG (GFS_BOUNDARY (boundary)));
+fflush (DEBUG);
+#endif
+    MPI_Isend (&boundary->sndcount, 1, MPI_UNSIGNED,
+	       mpi->process,
+	       TAG (GFS_BOUNDARY (boundary)),
+	       mpi->comm,
+	       &(mpi->request[mpi->nrequest++]));
+    gts_range_add_value (&domain->mpi_messages, sizeof (guint));
+  }
+#ifdef DEBUG
+fprintf (DEBUG, "%d send to %d with tag %d, size %d\n",
+	 domain->pid, 
+	 mpi->process,
+	 TAG (GFS_BOUNDARY (boundary)),
+	 boundary->sndcount);
+fflush (DEBUG);
+#endif
+  MPI_Isend (boundary->sndbuf->data, boundary->sndcount, MPI_DOUBLE,
+	     mpi->process,
+	     TAG (GFS_BOUNDARY (boundary)),
+	     mpi->comm,
+	     &(mpi->request[mpi->nrequest++]));
+  gts_range_add_value (&domain->mpi_messages, 
+                       sizeof (gdouble)*boundary->sndcount);
+}
+
+static void receive (GfsBoundary * bb,
+		     FttTraverseFlags flags,
+		     gint max_depth)
+{
+  GfsBoundaryPeriodic * boundary = GFS_BOUNDARY_PERIODIC (bb);
+  GfsBoundaryMpi * mpi = GFS_BOUNDARY_MPI (bb);
+  GfsDomain * domain = gfs_box_domain (bb->box);
+  MPI_Status status;
+  gint count;
+
+  if (domain->pid < 0)
+    return;
+
+#ifdef PROFILE_MPI
+  gdouble start, end;
+
+  start = MPI_Wtime ();
+#endif /* PROFILE_MPI */
+
+  if (GFS_BOUNDARY (boundary)->type == GFS_BOUNDARY_MATCH_VARIABLE) {
+#ifdef DEBUG
+fprintf (DEBUG, "%d wait on %d with tag %d for match variable size\n",
+	 gfs_box_domain (bb->box)->pid,
+	 mpi->process,
+	 MATCHING_TAG (GFS_BOUNDARY (boundary)));
+fflush (DEBUG);
+#endif
+    MPI_Recv (&boundary->rcvcount, 1, MPI_UNSIGNED,
+	      mpi->process,
+	      MATCHING_TAG (GFS_BOUNDARY (boundary)),
+	      mpi->comm,
+	      &status);
+#ifdef PROFILE_MPI
+    end = MPI_Wtime ();
+    gts_range_add_value (&domain->mpi_wait, end - start);
+    start = MPI_Wtime ();
+#endif /* PROFILE_MPI */
+    if (boundary->rcvcount > boundary->rcvbuf->len)
+      g_array_set_size (boundary->rcvbuf, boundary->rcvcount);
+  }
+  else
+    boundary->rcvcount = boundary->sndcount;
+#ifdef DEBUG
+  fprintf (DEBUG, "%d wait on %d with tag %d\n",
+	   gfs_box_domain (bb->box)->pid,
+	   mpi->process,
+	   MATCHING_TAG (GFS_BOUNDARY (boundary)));
+fflush (DEBUG);
+#endif
+  g_assert (boundary->rcvcount <= boundary->rcvbuf->len);
+  MPI_Recv (boundary->rcvbuf->data,
+	    boundary->rcvcount,
+	    MPI_DOUBLE,
+	    mpi->process,
+	    MATCHING_TAG (GFS_BOUNDARY (boundary)),
+	    mpi->comm,
+	    &status);
+  MPI_Get_count (&status, MPI_DOUBLE, &count);
+#ifdef DEBUG
+  fprintf (DEBUG, "src: %d tag: %d error: %d\n", 
+	   status.MPI_SOURCE, status.MPI_TAG, status.MPI_ERROR);
+  if (count == MPI_UNDEFINED) {
+    fprintf (DEBUG, "%d on tag %d: count is undefined!\n",
+	     gfs_box_domain (bb->box)->pid,
+	     MATCHING_TAG (GFS_BOUNDARY (boundary)));
+    g_assert_not_reached ();
+  }
+  else if (count != boundary->rcvcount) {
+    fprintf (DEBUG, "%d on tag %d: count = %d boundary->rcvcount = %d\n",
+	     gfs_box_domain (bb->box)->pid,
+	     MATCHING_TAG (GFS_BOUNDARY (boundary)),
+	     count, boundary->rcvcount);
+    g_assert_not_reached ();
+  }
+#else
+  g_assert (count == boundary->rcvcount);
+#endif
+
+#ifdef PROFILE_MPI
+  end = MPI_Wtime ();
+  gts_range_add_value (&domain->mpi_wait, end - start);
+#endif /* PROFILE_MPI */
+
+  (* gfs_boundary_periodic_class ()->receive) (bb, flags, max_depth);
+}
+
+static void synchronize (GfsBoundary * bb)
+{
+  GfsBoundaryMpi * boundary = GFS_BOUNDARY_MPI (bb);
+  MPI_Status status;
+  guint i;
+#ifdef PROFILE_MPI
+  GfsDomain * domain = gfs_box_domain (bb->box);
+  gdouble start, end;
+
+  start = MPI_Wtime ();
+#endif /* PROFILE_MPI */
+
+  /* wait for completion of non-blocking send(s) */
+  for (i = 0; i < boundary->nrequest; i++)
+    MPI_Wait (&(boundary->request[i]), &status);
+#ifdef PROFILE_MPI
+  end = MPI_Wtime ();
+  gts_range_add_value (&domain->mpi_wait, end - start);
+#endif /* PROFILE_MPI */
+  boundary->nrequest = 0;
+#ifdef DEBUG
+  /*  rewind (DEBUG); */
+  fprintf (DEBUG, "==== %d synchronised ====\n",
+	   gfs_box_domain (bb->box)->pid);
+  fflush (DEBUG);
+#endif
+  (* gfs_boundary_periodic_class ()->synchronize) (bb);
+}
+
+#endif /* HAVE_MPI */
+
+static void gfs_boundary_mpi_class_init (GfsBoundaryClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = boundary_mpi_read;
+  GTS_OBJECT_CLASS (klass)->write = boundary_mpi_write;
+#ifdef HAVE_MPI
+  klass->send        = send;
+  klass->receive     = receive;
+  klass->synchronize = synchronize;
+#endif /* HAVE_MPI */
+}
+
+static void gfs_boundary_mpi_init (GfsBoundaryMpi * boundary)
+{
+  boundary->process = -1; 
+  boundary->id = -1;
+#ifdef HAVE_MPI
+  boundary->nrequest = 0;
+  boundary->comm = MPI_COMM_WORLD;
+#ifdef DEBUG
+  if (mpi_debug == NULL) {
+    int rank;
+    MPI_Comm_rank (MPI_COMM_WORLD, &rank);
+    gchar * fname = g_strdup_printf ("mpi-%d", rank);
+    mpi_debug = fopen (fname, "w");
+    g_free (fname);
+  }
+#endif
+  static gboolean initialized = FALSE;
+  if (!initialized) {
+    int * tagub, flag, maxtag;
+    MPI_Attr_get (MPI_COMM_WORLD, MPI_TAG_UB, &tagub, &flag);
+    if (flag)
+      maxtag = *tagub;
+    else
+      maxtag = 32767; /* minimum value from MPI standard specification */
+    tag_shift = maxtag/FTT_NEIGHBORS;
+    initialized = TRUE;
+  }
+#endif /* HAVE_MPI */
+}
+
+GfsBoundaryClass * gfs_boundary_mpi_class (void)
+{
+  static GfsBoundaryClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_boundary_mpi_info = {
+      "GfsBoundaryMpi",
+      sizeof (GfsBoundaryMpi),
+      sizeof (GfsBoundaryClass),
+      (GtsObjectClassInitFunc) gfs_boundary_mpi_class_init,
+      (GtsObjectInitFunc) gfs_boundary_mpi_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_boundary_periodic_class ()),
+				  &gfs_boundary_mpi_info);
+  }
+
+  return klass;
+}
+
+GfsBoundaryMpi * gfs_boundary_mpi_new (GfsBoundaryClass * klass,
+				       GfsBox * box,
+				       FttDirection d,
+				       gint process,
+				       gint id)
+{
+  GfsBoundaryMpi * boundary;
+  boundary = GFS_BOUNDARY_MPI (gfs_boundary_periodic_new (klass, box, d, NULL));
+  boundary->process = process;
+#ifdef HAVE_MPI
+  int comm_size;
+  MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
+  g_return_val_if_fail (process >= 0 && process < comm_size, NULL);
+
+  if (id >= tag_shift)
+    g_warning ("GfsBoundaryMpi id (%d) is larger than the maximum MPI tag value\n"
+	       "allowed on this system (%d)", id, tag_shift);
+#endif /* HAVE_MPI */
+  boundary->id = id;
+
+  return boundary;
+}
diff --git a/src/mpi_boundary.h b/src/mpi_boundary.h
new file mode 100644
index 0000000..837f89d
--- /dev/null
+++ b/src/mpi_boundary.h
@@ -0,0 +1,68 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __MPI_BOUNDARY_H__
+#define __MPI_BOUNDARY_H__
+
+#include "boundary.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GfsBoundaryMpi         GfsBoundaryMpi;
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#  ifdef HAVE_MPI
+#    include <mpi.h>
+#  endif
+
+struct _GfsBoundaryMpi {
+  /*< private >*/
+  GfsBoundaryPeriodic parent;
+  gint process, id;
+
+#ifdef HAVE_MPI
+  MPI_Comm comm;
+  MPI_Request request[2];
+  guint nrequest;
+#endif /* HAVE_MPI */
+};
+
+#endif /* HAVE_CONFIG_H */
+
+#define GFS_BOUNDARY_MPI(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsBoundaryMpi,\
+					           gfs_boundary_mpi_class ())
+#define GFS_IS_BOUNDARY_MPI(obj)         (gts_object_is_from_class (obj,\
+						   gfs_boundary_mpi_class ()))
+     
+GfsBoundaryClass *    gfs_boundary_mpi_class    (void);
+GfsBoundaryMpi *      gfs_boundary_mpi_new      (GfsBoundaryClass * klass,
+						 GfsBox * box,
+						 FttDirection d,
+						 gint process,
+						 gint id);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MPI_BOUNDARY_H__ */
diff --git a/src/myc.h b/src/myc.h
new file mode 100644
index 0000000..ea4b317
--- /dev/null
+++ b/src/myc.h
@@ -0,0 +1,149 @@
+#define NOT_ZERO 1.e-30
+
+/*-----------------------------------------------------* 
+ *MYC - Mixed Youngs and Central Scheme                *
+ *-----------------------------------------------------*/
+/* 
+
+Known problems: the index [1][1][1], i.e. the central cell
+in the block, never occurs: neither in the central scheme
+nor in Youngs' method. Therefore an isolated droplet will have
+a normal with all components to zero. I took care of the
+division-by-zero issue, but not of this one.
+
+Ruben
+
+*/
+static void mycs(double c[3][3][3],double mxyz[3])
+{ 
+  double m1,m2,m[4][3],t0,t1,t2;
+  int cn;
+
+  /* write the plane as: sgn(mx) X =  my Y +  mz Z + alpha 
+                             m00 X = m01 Y + m02 Z + alpha */
+  m1 = c[0][1][0] + c[0][1][2] + c[0][0][1] + c[0][2][1] + 
+       c[0][1][1];
+  m2 = c[2][1][0] + c[2][1][2] + c[2][0][1] + c[2][2][1] + 
+       c[2][1][1];
+  m[0][0] = m1 > m2 ? 1. : -1.;
+
+  m1 = c[0][0][1]+ c[2][0][1]+ c[1][0][1];
+  m2 = c[0][2][1]+ c[2][2][1]+ c[1][2][1];
+  m[0][1] = 0.5*(m1-m2);
+
+  m1 = c[0][1][0]+ c[2][1][0]+ c[1][1][0];
+  m2 = c[0][1][2]+ c[2][1][2]+ c[1][1][2];
+  m[0][2] = 0.5*(m1-m2);
+
+  /* write the plane as: sgn(my) Y =  mx X +  mz Z + alpha 
+                             m11 Y = m10 X + m12 Z + alpha */
+  m1 = c[0][0][1] + c[0][2][1] + c[0][1][1];
+  m2 = c[2][0][1] + c[2][2][1] + c[2][1][1];
+  m[1][0] = 0.5*(m1-m2);
+
+  m1 = c[1][0][0] + c[1][0][2] + c[2][0][1] + c[0][0][1] +
+       c[1][0][1];
+  m2 = c[1][2][0] + c[1][2][2] + c[2][2][1] + c[0][2][1] +
+       c[1][2][1];
+  m[1][1] = m1 > m2 ? 1. : -1.;
+
+  m1 = c[1][0][0]+ c[1][1][0]+ c[1][2][0];
+  m2 = c[1][0][2]+ c[1][1][2]+ c[1][2][2];
+  m[1][2] = 0.5*(m1-m2);
+
+  /* write the plane as: sgn(mz) Z =  mx X +  my Y + alpha 
+                             m22 Z = m20 X + m21 Y + alpha */
+
+  m1 = c[0][1][0]+ c[0][1][2]+ c[0][1][1];
+  m2 = c[2][1][0]+ c[2][1][2]+ c[2][1][1];
+  m[2][0] = 0.5*(m1-m2);
+
+  m1 = c[1][0][0]+ c[1][0][2]+ c[1][0][1];
+  m2 = c[1][2][0]+ c[1][2][2]+ c[1][2][1];
+  m[2][1] = 0.5*(m1-m2);
+
+  m1 = c[0][1][0] + c[2][1][0] + c[1][0][0] + c[1][2][0] +
+       c[1][1][0];
+  m2 = c[0][1][2] + c[2][1][2] + c[1][0][2] + c[1][2][2] +
+       c[1][1][2];
+  m[2][2] = m1 > m2 ? 1. : -1.;
+
+  /* normalize each set (mx,my,mz): |mx|+|my|+|mz| = 1 */
+  t0 = fabs(m[0][0]) + fabs(m[0][1]) + fabs(m[0][2]);
+  m[0][0] /= t0;
+  m[0][1] /= t0;
+  m[0][2] /= t0;
+
+  t0 = fabs(m[1][0]) + fabs(m[1][1]) + fabs(m[1][2]);
+  m[1][0] /= t0;
+  m[1][1] /= t0;
+  m[1][2] /= t0;
+
+  t0 = fabs(m[2][0]) + fabs(m[2][1]) + fabs(m[2][2]);
+  m[2][0] /= t0;
+  m[2][1] /= t0;
+  m[2][2] /= t0;
+
+  /* choose among the three central scheme */ 
+  t0 = fabs(m[0][0]);
+  t1 = fabs(m[1][1]);
+  t2 = fabs(m[2][2]);
+
+  cn = 0;
+  if (t1 > t0) {
+    t0 = t1;
+    cn = 1;
+  }
+  if (t2 > t0)
+    cn = 2;
+
+  /* Youngs-CIAM scheme */  
+  m1 = c[0][0][0] + c[0][2][0] + c[0][0][2] + c[0][2][2] +
+       2.*(c[0][0][1] + c[0][2][1] + c[0][1][0] + c[0][1][2]) +
+       4.*c[0][1][1];
+  m2 = c[2][0][0] + c[2][2][0] + c[2][0][2] + c[2][2][2] +
+       2.*(c[2][0][1] + c[2][2][1] + c[2][1][0] + c[2][1][2]) +
+       4.*c[2][1][1];
+  m[3][0] = m1-m2;
+
+  m1 = c[0][0][0] + c[0][0][2] + c[2][0][0] + c[2][0][2] +
+       2.*( c[0][0][1] + c[2][0][1] + c[1][0][0] + c[1][0][2]) +
+       4.*c[1][0][1];
+  m2 = c[0][2][0] + c[0][2][2] + c[2][2][0] + c[2][2][2] +
+       2.*(c[0][2][1] + c[2][2][1] + c[1][2][0] + c[1][2][2]) +
+       4.*c[1][2][1];
+  m[3][1] = m1-m2;
+
+  m1 = c[0][0][0] + c[0][2][0] + c[2][0][0] + c[2][2][0] +
+       2.*(c[0][1][0] + c[2][1][0] + c[1][0][0] + c[1][2][0]) +
+       4.*c[1][1][0];
+  m2 = c[0][0][2] + c[0][2][2] + c[2][0][2] + c[2][2][2] +
+       2.*(c[0][1][2] + c[2][1][2] + c[1][0][2] + c[1][2][2]) +
+       4.*c[1][1][2];
+  m[3][2] = m1-m2;
+
+  /* normalize the set (mx,my,mz): |mx|+|my|+|mz| = 1 */
+  t0 = fabs(m[3][0]) + fabs(m[3][1]) + fabs(m[3][2]) + NOT_ZERO;
+  m[3][0] /= t0;
+  m[3][1] /= t0;
+  m[3][2] /= t0;
+
+  /* choose between the previous choice and Youngs-CIAM */
+  t0 = fabs (m[3][0]);
+  t1 = fabs (m[3][1]);
+  t2 = fabs (m[3][2]);
+  if (t1 > t0)
+    t0 = t1;
+  if (t2 > t0)
+    t0 = t2;
+
+  if (fabs(m[cn][cn]) > t0)
+    cn = 3;
+
+  /* components of the normal vector */
+  mxyz[0] = m[cn][0];
+  mxyz[1] = m[cn][1];
+  mxyz[2] = m[cn][2];
+
+  return; 
+}
diff --git a/src/myc2d.h b/src/myc2d.h
new file mode 100644
index 0000000..7caf540
--- /dev/null
+++ b/src/myc2d.h
@@ -0,0 +1,66 @@
+#define NOT_ZERO 1.e-30
+
+/*-----------------------------------------------------*
+ *MYC - Mixed Youngs and Central Scheme (2D)           *
+ *-----------------------------------------------------*/
+static void mycs(double c[3][3],double mxy[2])
+{
+  int ix;
+  double c_t,c_b,c_r,c_l;
+  double mx0,my0,mx1,my1,mm1,mm2;
+  
+  /* top, bottom, right and left sums of c values */
+  c_t = c[0][2] + c[1][2] + c[2][2];
+  c_b = c[0][0] + c[1][0] + c[2][0];
+  c_r = c[2][0] + c[2][1] + c[2][2];
+  c_l = c[0][0] + c[0][1] + c[0][2];
+
+  /* consider two lines: sgn(my) Y =  mx0 X + alpha,
+     and: sgn(mx) X =  my0 Y + alpha */ 
+  mx0 = 0.5*(c_l-c_r);
+  my0 = 0.5*(c_b-c_t);
+
+  /* minimum coefficient between mx0 and my0 wins */
+  if (fabs(mx0) <= fabs(my0)) {
+    my0 = my0 > 0. ? 1. : -1.;
+    ix = 1;
+  }
+  else {
+    mx0 = mx0 > 0. ? 1. : -1.;
+    ix = 0;
+  }
+
+  /* Youngs' normal to the interface */
+  mm1 = c[0][0] + 2.0*c[0][1] + c[0][2];
+  mm2 = c[2][0] + 2.0*c[2][1] + c[2][2];
+  mx1 = mm1 - mm2;
+  mm1 = c[0][0] + 2.0*c[1][0] + c[2][0];
+  mm2 = c[0][2] + 2.0*c[1][2] + c[2][2];
+  my1 = mm1 - mm2;
+
+  /* choose between the best central and Youngs' scheme */ 
+  if (ix) {
+    mm1 = fabs(my1) + NOT_ZERO; 
+    mm1 = fabs(mx1)/mm1;
+    if (mm1 > fabs(mx0)) {
+      mx0 = mx1;
+      my0 = my1;
+    }
+  }
+  else {
+    mm1 = fabs(mx1) + NOT_ZERO; 
+    mm1 = fabs(my1)/mm1;
+    if (mm1 > fabs(my0)) {
+      mx0 = mx1;
+      my0 = my1;
+    }
+  }
+	
+  /* normalize the set (mx0,my0): |mx0|+|my0|=1 and
+     write the two components of the normal vector  */
+  mm1 = fabs(mx0) + fabs(my0) + NOT_ZERO; 
+  mxy[0] = mx0/mm1;
+  mxy[1] = my0/mm1;
+  
+  return;
+}
diff --git a/src/ocean.c b/src/ocean.c
new file mode 100644
index 0000000..8f27014
--- /dev/null
+++ b/src/ocean.c
@@ -0,0 +1,1313 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2004 Stéphane Popinet
+ * National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+
+#include "ocean.h"
+#include "timestep.h"
+#include "adaptive.h"
+#include "source.h"
+#include "vof.h"
+#include "graphic.h"
+
+#include "solid.h"
+
+static void reset_gradients (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** g = data[0];
+  guint * dimension = data[1];    
+  FttComponent c;
+
+  for (c = 0; c < *dimension; c++)
+    GFS_VARIABLE (cell, g[c]->i) = 0.;
+}
+
+static void correct_normal_velocity (FttCellFace * face,
+				     gpointer * data)
+{
+  GfsGradient g;
+  gdouble dp;
+  FttFaceType type;
+  GfsVariable * p = data[0];
+  GfsVariable ** gv = data[1];
+  gdouble * dt = data[2];
+  FttComponent c;
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  type = ftt_face_type (face);
+  c = face->d/2;
+
+  gfs_face_gradient (face, &g, p->i, -1);
+  dp = (g.b - g.a*GFS_VARIABLE (face->cell, p->i))/ftt_cell_size (face->cell);
+  if (!FTT_FACE_DIRECT (face))
+    dp = - dp;
+
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) -= dp*(*dt);
+  GFS_VARIABLE (face->cell, gv[c]->i) += dp;
+
+  if (ftt_face_type (face) == FTT_FINE_COARSE)
+    dp *= GFS_FACE_FRACTION_LEFT (face)/(GFS_FACE_FRACTION_RIGHT (face)*FTT_CELLS/2);
+  GFS_FACE_NORMAL_VELOCITY_RIGHT (face) -= dp*(*dt);
+  GFS_VARIABLE (face->neighbor, gv[c]->i) += dp;
+}
+
+static void scale_gradients (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** g = data[0];
+  guint * dimension = data[1];
+  FttCellNeighbors n;
+  FttComponent c;
+
+  ftt_cell_neighbors (cell, &n);
+  for (c = 0; c < *dimension; c++) {
+    FttCell * c1 = n.c[2*c], * c2 = n.c[2*c + 1];
+    
+    if (c1 && c2 && !GFS_CELL_IS_GRADIENT_BOUNDARY (c1) && !GFS_CELL_IS_GRADIENT_BOUNDARY (c2))
+      GFS_VARIABLE (cell, g[c]->i) /= 2.;
+  }
+}
+
+/**
+ * gfs_correct_normal_velocities_weighted:
+ * @domain: a #GfsDomain.
+ * @dimension: the number of dimensions (2 or 3).
+ * @p: the pressure field.
+ * @g: where to store the pressure gradient.
+ * @dt: the timestep.
+ * @weighted: whether to use fraction-weighting or not.
+ *
+ * Corrects the normal velocity field of @domain using @p and and @dt.
+ *
+ * Also allocates the @g variables and fills them with the centered gradient of @p.
+ */
+static void gfs_correct_normal_velocities_weighted (GfsDomain * domain,
+						    guint dimension,
+						    GfsVariable * p,
+						    GfsVariable ** g,
+						    gdouble dt,
+						    gboolean weighted)
+{
+  gpointer data[3];
+  FttComponent c;
+    
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (g != NULL);
+    
+  for (c = 0; c < dimension; c++)
+    g[c] = gfs_temporary_variable (domain);
+  gfs_variable_set_vector (g, dimension);
+  data[0] = g;
+  data[1] = &dimension;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) reset_gradients, data);
+  if (weighted) {
+    gfs_correct_normal_velocities (domain, dimension, p, g, dt);
+    gfs_scale_gradients (domain, dimension, g);
+  }
+  else {
+    data[0] = p;
+    data[1] = g;
+    data[2] = &dt;
+    gfs_domain_face_traverse (domain, dimension == 2 ? FTT_XY : FTT_XYZ,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) correct_normal_velocity, data);
+    data[0] = g;
+    data[1] = &dimension;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) scale_gradients, data);
+    for (c = 0; c < dimension; c++)
+      gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, g[c]);
+  }
+}
+
+#define THETA 0.5
+
+typedef struct {
+  GfsVariable * pn, * div, * divn, * dia;
+  gdouble dt, G;
+} FreeSurfaceParams;
+
+static void normal_divergence (FttCell * cell, FreeSurfaceParams * p)
+{
+  GFS_VARIABLE (cell, p->div->i) += (1. - THETA)*GFS_VARIABLE (cell, p->divn->i)/THETA;
+}
+
+static void scale_divergence_helmoltz (FttCell * cell, FreeSurfaceParams * p)
+{
+  gdouble h = ftt_cell_size (cell);
+  gdouble c = 2.*h*h/(THETA*p->G*p->dt*p->dt);
+
+  if (GFS_IS_MIXED (cell))
+#if FTT_2D
+    c *= GFS_STATE (cell)->solid->a;
+#else /* 3D */
+    c *= GFS_STATE (cell)->solid->s[FTT_FRONT];
+#endif /* 3D */
+
+  GFS_VARIABLE (cell, p->dia->i) = c;
+  GFS_VARIABLE (cell, p->div->i) = 2.*GFS_VARIABLE (cell, p->div->i)/p->dt -
+    c*GFS_VARIABLE (cell, p->pn->i);
+}
+
+/**
+ * gfs_free_surface_pressure:
+ * @toplayer: a #GfsDomain.
+ * @par: the multigrid paramaters.
+ * @apar: the advection parameters.
+ *
+ */
+static void gfs_free_surface_pressure (GfsDomain * toplayer,
+				       GfsMultilevelParams * par,
+				       GfsAdvectionParams * apar,
+				       GfsVariable * p,
+				       GfsVariable * div,
+				       GfsVariable * divn,
+				       GfsVariable * res,
+				       gdouble G)
+{
+  FreeSurfaceParams fp;
+  GfsVariable * res1;
+
+  g_return_if_fail (toplayer != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (apar != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (div != NULL);
+  g_return_if_fail (divn != NULL);
+  g_return_if_fail (G > 0.);
+
+  fp.pn = p;
+  fp.div = div;
+  fp.dia = gfs_temporary_variable (toplayer);
+  res1 = res ? res : gfs_temporary_variable (toplayer);
+  fp.divn = divn;
+  fp.dt = apar->dt;
+  fp.G = G;
+
+  /* compute MAC divergence */
+  gfs_domain_cell_traverse (toplayer, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) normal_divergence, &fp);
+  gfs_domain_cell_traverse (toplayer, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+  			    (FttCellTraverseFunc) scale_divergence_helmoltz, &fp);
+  
+  /* solve for pressure */
+  par->depth = gfs_domain_depth (toplayer);
+  gfs_residual (toplayer, 2, FTT_TRAVERSE_LEAFS, -1, p, fp.div, fp.dia, res1);
+  par->residual_before = par->residual = 
+    gfs_domain_norm_residual (toplayer, FTT_TRAVERSE_LEAFS, -1, apar->dt, res1);
+  par->niter = 0;
+  par->dimension = 2;
+  while (par->niter < par->nitermin ||
+	 (par->residual.infty > par->tolerance && par->niter < par->nitermax)) {
+#if 0
+    fprintf (stderr, "%d bias: %g first: %g second: %g infty: %g\n",
+	     par->niter, 
+	     par->residual.bias, 
+	     par->residual.first, 
+	     par->residual.second, 
+	     par->residual.infty);
+#endif
+    gfs_poisson_cycle (toplayer, par, p, fp.div, fp.dia, res1);
+    par->residual = gfs_domain_norm_residual (toplayer, FTT_TRAVERSE_LEAFS, -1, apar->dt, res1);
+    par->niter++;
+  }
+
+  if (!res)
+    gts_object_destroy (GTS_OBJECT (res1));
+  gts_object_destroy (GTS_OBJECT (fp.dia));
+}
+
+#if FTT_2D
+
+/* GfsOcean: Object */
+
+static void normal_velocities (GfsDomain * domain, GfsVariable ** u)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (div != NULL);
+
+  gfs_domain_face_traverse (domain, FTT_XY,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+  gfs_domain_face_traverse (domain, FTT_XY,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_interpolated_normal_velocity, u);
+}
+
+static void ocean_run (GfsSimulation * sim)
+{
+  GfsVariable * p, * div, * H, * res = NULL;
+  GfsFunction * fH;
+  GfsDomain * domain;
+  GSList * i;
+
+  domain = GFS_DOMAIN (sim);
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
+      res = i->data;
+    i = i->next;
+  }
+
+  p = gfs_variable_from_name (domain->variables, "P");
+  g_assert (p);
+  H = gfs_variable_from_name (domain->variables, "H");
+  g_assert (H);
+  fH = gfs_function_new_from_variable (gfs_function_class (), H);
+
+  div = gfs_temporary_variable (domain);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    GfsVariable * g[2];
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    gfs_simulation_set_timestep (sim);
+
+    normal_velocities (domain, gfs_domain_velocity (domain));
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_normal_divergence_2D, div);
+
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, p);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
+
+    gfs_poisson_coefficients (domain, fH);
+    gfs_correct_normal_velocities_weighted (domain, 2, p, g, 0., 
+					    sim->approx_projection_params.weighted);
+    gfs_centered_velocity_advection_diffusion (domain, 2,
+					       &sim->advection_params,
+					       g, g,
+					       sim->physical_params.alpha);
+    gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+    gfs_correct_centered_velocities (domain, 2, g, -sim->advection_params.dt/2.);
+    gts_object_destroy (GTS_OBJECT (g[0]));
+    gts_object_destroy (GTS_OBJECT (g[1]));
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gfs_domain_timer_start (domain, "free_surface_pressure");
+    GfsVariable * divn = gfs_temporary_variable (domain);
+    normal_velocities (domain, gfs_domain_velocity (domain));
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_normal_divergence_2D, divn);
+    gfs_free_surface_pressure (domain, &sim->approx_projection_params, &sim->advection_params,
+			       p, divn, div, res, sim->physical_params.g);
+    gts_object_destroy (GTS_OBJECT (divn));
+    gfs_correct_normal_velocities_weighted (domain, 2, p, g, sim->advection_params.dt/2., 
+					    sim->approx_projection_params.weighted);
+    gfs_correct_centered_velocities (domain, 2, g, sim->advection_params.dt/2.);
+    gts_object_destroy (GTS_OBJECT (g[0]));
+    gts_object_destroy (GTS_OBJECT (g[1]));
+    gfs_domain_timer_stop (domain, "free_surface_pressure");
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events),
+			 (GtsFunc) gts_object_destroy, NULL);
+
+  gts_object_destroy (GTS_OBJECT (div));
+  gts_object_destroy (GTS_OBJECT (fH));
+}
+
+static void gfs_ocean_class_init (GfsSimulationClass * klass)
+{
+  klass->run = ocean_run;
+}
+
+static void gfs_ocean_init (GfsOcean * object)
+{
+  GFS_SIMULATION (object)->approx_projection_params.weighted = 1;
+}
+
+GfsSimulationClass * gfs_ocean_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_ocean_info = {
+      "GfsOcean",
+      sizeof (GfsSimulation),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) gfs_ocean_class_init,
+      (GtsObjectInitFunc) gfs_ocean_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_ocean_info);
+  }
+
+  return klass;
+}
+
+#else /* 2D3 or 3D */
+
+/* GfsOcean: Object */
+
+#define MAC 0
+
+static void ocean_destroy (GtsObject * object)
+{
+  guint i;
+  GPtrArray * layer = GFS_OCEAN (object)->layer;
+
+  for (i = 0; i < layer->len; i++) {
+    GfsDomain * d = g_ptr_array_index (layer, i);
+    d->allocated = g_array_new (FALSE, TRUE, sizeof (gboolean));
+    gts_object_destroy (GTS_OBJECT (d));
+  }
+  g_ptr_array_free (layer, TRUE);
+
+  (* GTS_OBJECT_CLASS (gfs_ocean_class ())->parent_class->destroy) (object);  
+}
+
+#define MAXLEVEL 16
+
+static void ocean_read (GtsObject ** object, GtsFile * fp)
+{
+#if !FTT_2D3
+  /* fixme: lambda.z cannot be changed */
+  GfsSimulation * sim = GFS_SIMULATION (*object);
+  GFS_DOMAIN (sim)->lambda.z = 1./(1 << MAXLEVEL);
+#endif
+
+  (* GTS_OBJECT_CLASS (gfs_ocean_class ())->parent_class->read) (object, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_DOMAIN (*object)->refpos.z = -0.5;
+#if !FTT_2D3
+  g_assert (GFS_DOMAIN (sim)->lambda.z == 1./(1 << MAXLEVEL));
+  sim->physical_params.g /= sim->physical_params.L/* *GFS_DOMAIN (sim)->lambda.z*/;
+  GfsVariable * H = gfs_variable_from_name (GFS_DOMAIN (sim)->variables, "H");
+  g_assert (H);
+  H->units = 1. - log(/*GFS_DOMAIN (sim)->lambda.z*/1.)/log(sim->physical_params.L);
+  GFS_DOMAIN (sim)->lambda.z = 1./(1 << MAXLEVEL);
+#endif
+}
+
+#if !FTT_2D3
+static void ocean_write (GtsObject * object, FILE * fp)
+{
+  FttVector * lambda = &GFS_DOMAIN (object)->lambda;
+  GfsPhysicalParams * p = &GFS_SIMULATION (object)->physical_params;
+  gdouble g = p->g;
+
+  lambda->z *= 1 << MAXLEVEL;
+  p->g *= p->L*lambda->z;
+  (* GTS_OBJECT_CLASS (gfs_ocean_class ())->parent_class->write) (object, fp);
+  lambda->z /= 1 << MAXLEVEL;
+  p->g = g;
+}
+#endif /* 3D */
+
+static void new_layer (GfsOcean * ocean)
+{
+  GfsDomain * domain = GFS_DOMAIN (ocean);
+  GfsDomain * d = GFS_DOMAIN (gts_object_new (GTS_OBJECT_CLASS (gfs_domain_class ())));
+  
+  d->rootlevel = domain->rootlevel;
+  d->refpos = domain->refpos;
+  d->lambda = domain->lambda;
+  g_array_free (d->allocated, TRUE);
+  d->allocated = domain->allocated;
+  g_ptr_array_add (ocean->layer, d);
+}
+
+static void add_layer (GfsBox * box, GfsDomain * domain)
+{
+  if (box->neighbor[FTT_FRONT] == NULL || GFS_IS_BOUNDARY (box->neighbor[FTT_FRONT])) {
+    GPtrArray * layer = GFS_OCEAN (domain)->layer;
+    GtsObject * n;
+    guint l = 0;
+
+    gts_container_add (GTS_CONTAINER (g_ptr_array_index (layer, l++)), GTS_CONTAINEE (box));
+    n = box->neighbor[FTT_BACK];
+    while (GFS_IS_BOX (n)) {
+      if (l == layer->len)
+	new_layer (GFS_OCEAN (domain));
+      gts_container_add (GTS_CONTAINER (g_ptr_array_index (layer, l++)), GTS_CONTAINEE (n));
+      n = GFS_BOX (n)->neighbor[FTT_BACK];
+    }
+  }
+}
+
+static void ocean_post_read (GfsDomain * domain, GtsFile * fp)
+{
+  (* GFS_DOMAIN_CLASS (GTS_OBJECT_CLASS (gfs_ocean_class ())->parent_class)->post_read) 
+    (domain, fp);
+
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) add_layer, domain);
+  g_assert (GFS_OCEAN (domain)->layer->len > 0);
+  GFS_OCEAN (domain)->toplayer = g_ptr_array_index (GFS_OCEAN (domain)->layer, 0);
+}
+
+static void compute_w (FttCell * c, GfsVariable * W)
+{
+  FttCell * n;
+  guint level = ftt_cell_level (c);
+  gdouble wf = 0., w = 0.;
+
+  while ((n = ftt_cell_neighbor (c, FTT_BACK)))
+    c = n;
+  while (c) {
+    GfsStateVector * s = GFS_STATE (c);
+
+    g_assert (FTT_CELL_IS_LEAF (c) && ftt_cell_level (c) == level);
+    s->f[FTT_BACK].un = w;
+    wf += (s->f[FTT_LEFT].v*s->f[FTT_LEFT].un - s->f[FTT_RIGHT].v*s->f[FTT_RIGHT].un +
+    	   s->f[FTT_BOTTOM].v*s->f[FTT_BOTTOM].un - s->f[FTT_TOP].v*s->f[FTT_TOP].un);
+    if (GFS_IS_MIXED (c))
+      s->f[FTT_FRONT].un = w = GFS_STATE (c)->solid->s[FTT_FRONT] > 0. ? 
+	wf/GFS_STATE (c)->solid->s[FTT_FRONT] : 0.;
+    else
+      s->f[FTT_FRONT].un = w = wf;
+    GFS_VARIABLE (c, W->i) = (s->f[FTT_BACK].un + s->f[FTT_FRONT].un)/2.;
+    c = ftt_cell_neighbor (c, FTT_FRONT);
+  }
+}
+
+static void compute_div (FttCell * c, GfsVariable * W)
+{
+  guint level = ftt_cell_level (c);
+  gdouble wf = 0., size = ftt_cell_size (c);
+#if !FTT_2D3
+  g_assert (level <= MAXLEVEL);
+  size *= 1 << (MAXLEVEL - level);
+#endif
+
+  while (c) {
+    GfsStateVector * s = GFS_STATE (c);
+    GfsSolidVector * solid = s->solid;
+
+    g_assert (FTT_CELL_IS_LEAF (c) && ftt_cell_level (c) == level);
+    if (solid)
+      wf += (solid->s[FTT_RIGHT]*s->f[FTT_RIGHT].un - solid->s[FTT_LEFT]*s->f[FTT_LEFT].un +
+	     solid->s[FTT_TOP]*s->f[FTT_TOP].un - solid->s[FTT_BOTTOM]*s->f[FTT_BOTTOM].un);
+    else
+      wf += (s->f[FTT_RIGHT].un - s->f[FTT_LEFT].un +
+	     s->f[FTT_TOP].un - s->f[FTT_BOTTOM].un);
+    GFS_VARIABLE (c, W->i) = wf*size;
+    c = ftt_cell_neighbor (c, FTT_BACK);
+  }
+}
+
+/* fixme: this is ok for one layer but what about several? */
+static gdouble height (FttCell * cell)
+{
+  if (!GFS_IS_MIXED (cell))
+    return 1.;
+  gdouble f = GFS_STATE (cell)->solid->s[FTT_FRONT];
+  g_assert (f);
+#if FTT_2D3
+  return GFS_STATE (cell)->solid->a/f;
+#else /* 3D */
+  guint level = ftt_cell_level (cell);
+  g_assert (level <= MAXLEVEL);
+  return GFS_STATE (cell)->solid->a/f*(1 << (MAXLEVEL - level));
+#endif /* 3D */
+}
+
+static void compute_H (FttCell * cell, GfsVariable * H)
+{
+  GFS_VARIABLE (cell, H->i) = height (cell);
+}
+
+static void face_interpolated_normal_velocity (const FttCellFace * face, GfsVariable ** v)
+{
+  gdouble u;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (v != NULL);
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  guint i = v[face->d/2]->i;
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    u = (GFS_VARIABLE (face->cell, i) + GFS_VARIABLE (face->neighbor, i))/2.; 
+    break;
+  case FTT_FINE_COARSE: {
+    gdouble w1 = height (face->cell), w2 = height (face->neighbor);
+    w1 = 2.*w1/(w1 + w2);
+    u = w1*gfs_face_interpolated_value (face, i) + (1. - w1)*GFS_VARIABLE (face->neighbor, i);
+    break;
+  }
+  default:
+     g_assert_not_reached ();
+  }
+
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) = u;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) = u;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_FACE_NORMAL_VELOCITY_RIGHT (face) += 
+      u*GFS_FACE_FRACTION_LEFT (face)/(GFS_FACE_FRACTION_RIGHT (face)*
+				       FTT_CELLS_DIRECTION (face->d));
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void depth_integrated_divergence (GfsDomain * domain, GfsVariable * div)
+{
+  /* compute MAC velocities from centered velocities */
+#if !MAC
+  gfs_domain_face_traverse (domain, FTT_XY,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+  gfs_domain_face_traverse (domain, FTT_XY,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) face_interpolated_normal_velocity,
+			    gfs_domain_velocity (domain));
+#endif
+  /* barotropic divergence */
+  gfs_domain_cell_traverse_boundary (domain, FTT_FRONT,
+				     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				     (FttCellTraverseFunc) compute_div, div);
+}
+
+static void compute_coeff (FttCell * c)
+{
+  guint level = ftt_cell_level (c);
+  gdouble wf[FTT_NEIGHBORS_2D] = {0.,0.,0.,0.}, size = 1.;
+#if !FTT_2D3
+  g_assert (level <= MAXLEVEL);
+  size = 1 << (MAXLEVEL - level);
+#endif
+
+  while (c) {
+    GfsStateVector * s = GFS_STATE (c);
+    FttDirection d;
+
+    g_assert (FTT_CELL_IS_LEAF (c) && ftt_cell_level (c) == level);
+    for (d = 0; d < FTT_NEIGHBORS_2D; d++) {
+      wf[d] += s->f[d].v*size;
+      s->f[d].v = wf[d];
+    }
+    c = ftt_cell_neighbor (c, FTT_BACK);
+  }
+}
+
+static void face_coeff_from_below (FttCell * cell)
+{
+  FttDirection d;
+  GfsFaceStateVector * f = GFS_STATE (cell)->f;
+  guint neighbors = 0;
+
+  for (d = 0; d < FTT_NEIGHBORS_2D; d++) {
+    FttCellChildren child;
+    guint i, n;
+
+    f[d].v = 0.;
+    n = ftt_cell_children_direction (cell, d, &child);
+    for (i = 0; i < n; i++)
+      if (child.c[i])
+	f[d].v += GFS_STATE (child.c[i])->f[d].v;
+    f[d].v /= 2;
+
+    FttCell * neighbor;
+    if (f[d].v > 0. && (neighbor = ftt_cell_neighbor (cell, d)) && !GFS_CELL_IS_BOUNDARY (neighbor))
+      neighbors++;
+  }
+
+  if (neighbors == 1)
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      f[d].v = 0.;
+}
+
+static void depth_integrated_coefficients (GfsDomain * domain)
+{
+  gfs_poisson_coefficients (domain, NULL);
+  gfs_domain_cell_traverse_boundary (domain, FTT_FRONT,
+				     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				     (FttCellTraverseFunc) compute_coeff, NULL);
+  gfs_domain_cell_traverse_boundary (domain, FTT_FRONT,
+				     FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				     (FttCellTraverseFunc) face_coeff_from_below, NULL);
+}
+
+static void ocean_run (GfsSimulation * sim)
+{
+  GfsVariable * p, * div, * H, * res = NULL;
+  GfsDomain * domain, * toplayer;
+  GSList * i;
+
+  domain = GFS_DOMAIN (sim);
+  toplayer = GFS_OCEAN (sim)->toplayer;
+
+  gfs_simulation_refine (sim);
+
+  H = gfs_variable_from_name (domain->variables, "H");
+  g_assert (H);
+
+  gfs_domain_cell_traverse (toplayer, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) compute_H, H);
+
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_init, sim);
+
+  gfs_set_merged (domain);
+  i = domain->variables;
+  while (i) {
+    gfs_event_init (i->data, sim);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, i->data);
+    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
+      res = i->data;
+    i = i->next;
+  }
+
+  p = gfs_variable_from_name (domain->variables, "P");
+  g_assert (p);
+
+  div = gfs_temporary_variable (domain);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    GfsVariable * g[2];
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    gfs_simulation_set_timestep (sim);
+
+    depth_integrated_divergence (domain, div);
+
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, p);
+
+    /* baroclinic terms */
+#if !MAC
+    gfs_predicted_face_velocities (domain, 2, &sim->advection_params);
+
+    gfs_domain_timer_start (domain, "correct_normal_velocities");
+    gfs_poisson_coefficients (domain, NULL);
+    gfs_correct_normal_velocities_weighted (domain, 2, p, g, sim->advection_params.dt/2.,
+					    sim->approx_projection_params.weighted);
+    gfs_domain_cell_traverse_boundary (domain, FTT_FRONT,
+				       FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				       (FttCellTraverseFunc) compute_w, 
+				       gfs_variable_from_name (domain->variables, "W"));
+    gfs_domain_timer_stop (domain, "correct_normal_velocities");
+
+    i = domain->variables;
+    while (i) {
+      if (GFS_IS_VARIABLE_TRACER_VOF (i->data)) {
+	GfsVariableTracer * t = i->data;
+
+	t->advection.dt = sim->advection_params.dt;
+	gfs_tracer_vof_advection (domain, &t->advection);
+	gfs_domain_variable_centered_sources (domain, i->data, i->data, t->advection.dt);
+      }
+      else if (GFS_IS_VARIABLE_TRACER (i->data)) {
+	GfsVariableTracer * t = i->data;
+	
+	t->advection.dt = sim->advection_params.dt;
+	gfs_tracer_advection_diffusion (domain, &t->advection);
+      }
+      i = i->next;
+    }
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
+
+    gfs_centered_velocity_advection_diffusion (domain, 2,
+					       &sim->advection_params,
+					       g, g,
+					       sim->physical_params.alpha);
+    gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+    gfs_correct_centered_velocities (domain, 2, g, -sim->advection_params.dt/2.);
+#else
+    gfs_poisson_coefficients (domain, NULL);
+    gfs_correct_normal_velocities_weighted (domain, 2, p, g, sim->advection_params.dt/2.,
+					    sim->approx_projection_params.weighted);
+    gfs_correct_centered_velocities (domain, 2, g, sim->advection_params.dt/2.);
+#endif
+    gts_object_destroy (GTS_OBJECT (g[0]));
+    gts_object_destroy (GTS_OBJECT (g[1]));
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gfs_domain_timer_start (domain, "free_surface_pressure");
+    GfsVariable * divn = gfs_temporary_variable (domain);
+    depth_integrated_divergence (domain, divn);
+    depth_integrated_coefficients (domain);
+    gfs_free_surface_pressure (toplayer, &sim->approx_projection_params, &sim->advection_params,
+			       p, divn, div, res, 
+			       sim->physical_params.g/GFS_OCEAN (domain)->layer->len);
+    gts_object_destroy (GTS_OBJECT (divn));
+
+    gfs_poisson_coefficients (domain, NULL);
+    gfs_correct_normal_velocities_weighted (domain, 2, p, g, sim->advection_params.dt/2.,
+					    sim->approx_projection_params.weighted);
+    gfs_correct_centered_velocities (domain, 2, g, sim->advection_params.dt/2.);
+    gts_object_destroy (GTS_OBJECT (g[0]));
+    gts_object_destroy (GTS_OBJECT (g[1]));
+    
+    gfs_domain_timer_stop (domain, "free_surface_pressure");
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events),
+			 (GtsFunc) gts_object_destroy, NULL);
+
+  gts_object_destroy (GTS_OBJECT (div));
+}
+
+static void gfs_ocean_class_init (GfsSimulationClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = ocean_destroy;
+  GTS_OBJECT_CLASS (klass)->read = ocean_read;
+#if !FTT_2D3
+  GTS_OBJECT_CLASS (klass)->write = ocean_write;
+#endif
+  GFS_DOMAIN_CLASS (klass)->post_read = ocean_post_read;
+  klass->run = ocean_run;
+}
+
+static void gfs_ocean_init (GfsOcean * object)
+{
+  gfs_domain_add_variable (GFS_DOMAIN (object), "H", "Depth");
+  GFS_SIMULATION (object)->approx_projection_params.weighted = 1;
+  object->layer = g_ptr_array_new ();
+  new_layer (object);
+}
+
+GfsSimulationClass * gfs_ocean_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_ocean_info = {
+      "GfsOcean",
+      sizeof (GfsOcean),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) gfs_ocean_class_init,
+      (GtsObjectInitFunc) gfs_ocean_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_ocean_info);
+  }
+
+  return klass;
+}
+
+static void hydrostatic_pressure (FttCell * cell, gpointer * data)
+{
+  GfsVariable * vp = data[0];
+  GfsVariable * rho = data[1];
+  gdouble * g = data[2];
+  gdouble r = GFS_VARIABLE (cell, rho->i), p = (*g)*r/2., r1;
+  FttCellFace f;
+  
+  GFS_VARIABLE (cell, vp->i) = p;
+  f.cell = cell;
+  f.d = FTT_BACK;
+  f.neighbor = ftt_cell_neighbor (f.cell, f.d);
+  while (f.neighbor) {
+    g_assert (ftt_face_type (&f) == FTT_FINE_FINE);
+    r1 = gfs_face_interpolated_value (&f, rho->i);
+    /* g_assert (r1 >= r); */
+    r = r1;
+    GFS_VARIABLE (f.neighbor, vp->i) = p = p + (*g)*r;
+    f.cell = f.neighbor;
+    f.neighbor = ftt_cell_neighbor (f.cell, f.d);
+  }
+}
+
+/**
+ * gfs_hydrostatic_pressure:
+ * @domain: a #GfsDomain.
+ * @p: the hydrostatic pressure.
+ * @rho: the density.
+ * @g: the acceleration.
+ *
+ * Computes the hydrostatic pressure @p in @domain using the density
+ * @rho.
+ */
+void gfs_hydrostatic_pressure (GfsDomain * domain,
+			       GfsVariable * p,
+			       GfsVariable * rho,
+			       gdouble g)
+{
+  gpointer data[3];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (rho != NULL);
+  g_return_if_fail (g >= 0.);
+
+  g /= GFS_OCEAN (domain)->layer->len;
+  data[0] = p;
+  data[1] = rho;
+  data[2] = &g;
+  gfs_domain_cell_traverse_boundary (domain, FTT_FRONT,
+				     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				     (FttCellTraverseFunc) hydrostatic_pressure, data);
+}
+
+/* GfsSourceHydrostatic: Object */
+
+static void gfs_source_hydrostatic_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE_HYDROSTATIC (o)->ph1)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_HYDROSTATIC (o)->ph1));
+
+  (* GTS_OBJECT_CLASS (gfs_source_hydrostatic_class ())->parent_class->destroy) (o);
+}
+
+
+static void gfs_source_hydrostatic_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  GfsSourceHydrostatic * sh;
+
+  if (GTS_OBJECT_CLASS (gfs_source_hydrostatic_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_hydrostatic_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  sh = GFS_SOURCE_HYDROSTATIC (*o);
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (rho)");
+    return;
+  }
+  sh->rho = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (sh->rho == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (ph)");
+    return;
+  }
+  if (!(sh->ph = gfs_domain_get_or_add_variable (domain, fp->token->str, "Hydrostatic pressure"))) {
+    gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  sh->ph1 = gfs_temporary_variable (domain);
+}
+
+static void gfs_source_hydrostatic_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_hydrostatic_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s %s",
+	   GFS_SOURCE_HYDROSTATIC (o)->rho->name, 
+	   GFS_SOURCE_HYDROSTATIC (o)->ph->name);
+}
+
+static gdouble gfs_source_hydrostatic_mac_value (GfsSourceGeneric * s,
+						 FttCell * cell,
+						 GfsVariable * v)
+{
+  return - gfs_center_gradient (cell, v->component,
+				GFS_SOURCE_HYDROSTATIC (s)->ph1->i)/ftt_cell_size (cell);
+}
+
+static gdouble gfs_source_hydrostatic_centered_value (GfsSourceGeneric * s,
+						      FttCell * cell,
+						      GfsVariable * v)
+{
+  GfsSourceHydrostatic * b = GFS_SOURCE_HYDROSTATIC (s);
+
+  return - (gfs_center_gradient (cell, v->component, b->ph->i) + 
+	    gfs_center_gradient (cell, v->component, b->ph1->i))/(2.*ftt_cell_size (cell));
+}
+
+static void copy_ph (FttCell * cell, GfsSourceHydrostatic * s)
+{
+  GFS_VARIABLE (cell, s->ph1->i) = GFS_VARIABLE (cell, s->ph->i);
+}
+
+static gboolean gfs_source_hydrostatic_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsSourceHydrostatic * s = GFS_SOURCE_HYDROSTATIC (event);
+
+    if (s->not_first) {
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) copy_ph, s);
+      gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1, s->ph1);
+    }
+    else {
+      gfs_hydrostatic_pressure (GFS_DOMAIN (sim), s->ph1, s->rho, sim->physical_params.g);
+      gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1, s->ph1);
+      s->not_first = TRUE;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_source_hydrostatic_event_half (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsSourceHydrostatic * s = GFS_SOURCE_HYDROSTATIC (event);
+
+  gfs_hydrostatic_pressure (GFS_DOMAIN (sim), s->ph, s->rho, sim->physical_params.g);
+  gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1, s->ph);
+}
+
+static void gfs_source_hydrostatic_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_source_hydrostatic_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_source_hydrostatic_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_source_hydrostatic_write;
+
+  GFS_EVENT_CLASS (klass)->event = gfs_source_hydrostatic_event;
+  GFS_EVENT_CLASS (klass)->event_half = gfs_source_hydrostatic_event_half;
+}
+
+static void gfs_source_hydrostatic_init (GfsSourceGeneric * s)
+{
+  s->mac_value = gfs_source_hydrostatic_mac_value;
+  s->centered_value = gfs_source_hydrostatic_centered_value;
+}
+
+GfsSourceGenericClass * gfs_source_hydrostatic_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_hydrostatic_info = {
+      "GfsSourceHydrostatic",
+      sizeof (GfsSourceHydrostatic),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_hydrostatic_class_init,
+      (GtsObjectInitFunc) gfs_source_hydrostatic_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_velocity_class ()),
+				  &gfs_source_hydrostatic_info);
+  }
+
+  return klass;
+}
+
+#endif /* 2D3 or 3D */
+
+/* GfsSourceFriction: Object */
+
+static void gfs_source_friction_destroy (GtsObject * o)
+{
+  FttComponent c;
+
+  for (c = 0; c <  FTT_DIMENSION; c++)
+    if (GFS_SOURCE_FRICTION (o)->u[c])
+      gts_object_destroy (GTS_OBJECT (GFS_SOURCE_FRICTION (o)->u[c]));
+
+  (* GTS_OBJECT_CLASS (gfs_source_friction_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_source_friction_read (GtsObject ** o, GtsFile * fp)
+{
+  FttComponent c;
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+
+  (* GTS_OBJECT_CLASS (gfs_source_friction_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsVariable h)");
+    return;
+  }
+  GFS_SOURCE_FRICTION (*o)->h = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (GFS_SOURCE_FRICTION (*o)->h == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  /* fixme: units? */
+  GFS_SOURCE_FRICTION (*o)->f = gfs_read_constant (fp, domain);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  for (c = 0; c <  FTT_DIMENSION; c++)
+    GFS_SOURCE_FRICTION (*o)->u[c] = gfs_temporary_variable (domain);
+}
+
+static void gfs_source_friction_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_friction_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s %g", GFS_SOURCE_FRICTION (o)->h->name, GFS_SOURCE_FRICTION (o)->f);
+}
+
+static gdouble gfs_source_friction_saved_value (GfsSourceGeneric * s, 
+						FttCell * cell, 
+						GfsVariable * v)
+{
+  gdouble H = GFS_VARIABLE (cell, GFS_SOURCE_FRICTION (s)->h->i);
+
+  g_assert (H > 0.);
+  return - GFS_SOURCE_FRICTION (s)->f*
+    GFS_VARIABLE (cell, GFS_SOURCE_FRICTION (s)->u[v->component]->i)/H;
+}
+
+static void save_velocity (FttCell * cell, GfsSourceFriction * s)
+{
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    GFS_VARIABLE (cell, s->u[c]->i) = GFS_VARIABLE (cell, GFS_SOURCE_VELOCITY (s)->v[c]->i);
+}
+
+static gboolean gfs_source_friction_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class)->event)
+      (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) save_velocity, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_source_friction_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_source_friction_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_source_friction_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_source_friction_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_source_friction_event;
+}
+
+static void gfs_source_friction_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = gfs_source_friction_saved_value;
+}
+
+GfsSourceGenericClass * gfs_source_friction_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_friction_info = {
+      "GfsSourceFriction",
+      sizeof (GfsSourceFriction),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_friction_class_init,
+      (GtsObjectInitFunc) gfs_source_friction_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_velocity_class ()),
+				  &gfs_source_friction_info);
+  }
+
+  return klass;
+}
+
+/* GfsBcFlather: Object */
+
+/* Also check whether modules/tide.mod needs upgrading when modyifing this class */
+
+static void bc_flather_write (GtsObject * o, FILE * fp)
+{
+  GfsBcFlather * bc = GFS_BC_FLATHER (o);
+
+  (* GTS_OBJECT_CLASS (gfs_bc_flather_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s %s", bc->h->name, bc->p->name);
+  if (bc->val)
+    gfs_function_write (bc->val, fp);
+}
+
+static void set_gradient_boundary (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_GRADIENT_BOUNDARY;
+}
+
+static void bc_flather_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBcFlather * bc = GFS_BC_FLATHER (*o);
+  GfsDomain * domain = gfs_box_domain (GFS_BC (bc)->b->box);
+
+  (* GTS_OBJECT_CLASS (gfs_bc_flather_class ())->parent_class->read) (o, fp);
+
+  gfs_function_set_units (GFS_BC_VALUE (bc)->val, 1.);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (h)");
+    return;
+  }
+  bc->h = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (bc->h == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (p)");
+    return;
+  }
+  bc->p = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (bc->p == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+  if (bc->val == NULL)
+    bc->val = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_read (bc->val, gfs_box_domain (GFS_BC (bc)->b->box), fp);
+  gfs_function_set_units (bc->val, 1.);
+
+  ftt_cell_traverse (GFS_BC (bc)->b->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		     (FttCellTraverseFunc) set_gradient_boundary, NULL);
+}
+
+static void bc_flather_destroy (GtsObject * o)
+{
+  if (GFS_BC_FLATHER (o)->val)
+    gts_object_destroy (GTS_OBJECT (GFS_BC_FLATHER (o)->val));
+
+  (* GTS_OBJECT_CLASS (gfs_bc_flather_class ())->parent_class->destroy) (o);
+}
+
+static gdouble flather_value (FttCellFace * f, GfsBc * b)
+{
+  /* fixme: this will not work for multilayer domains */
+  guint d, nb = 0;
+  FttCellNeighbors n;
+  gdouble H;
+
+  ftt_cell_neighbors (f->neighbor, &n);
+  for (d = 0; d < FTT_NEIGHBORS_2D; d++)
+    if (n.c[d] != NULL && GFS_CELL_IS_BOUNDARY(n.c[d]) && nb++ > 0)
+      /* if the boundary cell is bounded by more than one boundary -> no flux */
+      return 0.;
+
+  GfsSimulation * sim = GFS_SIMULATION (gfs_box_domain (b->b->box));
+  H = gfs_face_interpolated_value (f, GFS_BC_FLATHER (b)->h->i);
+  if (H > 10./sim->physical_params.L) { /* fixme: this a bit crappy */
+    gdouble cg = sqrt (sim->physical_params.g*H);
+    /* non-dimensional pressure at the boundary */
+    gdouble lz = GFS_DOMAIN (sim)->lambda.z;
+#if !FTT_2D && !FTT_2D3
+    lz *= 1 << MAXLEVEL;
+#endif
+    gdouble pb = gfs_function_face_value (GFS_BC_FLATHER (b)->val, f)*sim->physical_params.g*lz;
+    
+    return gfs_function_face_value (GFS_BC_VALUE (b)->val, f) +
+      (FTT_FACE_DIRECT (f) ? -1. : 1.)*
+      (GFS_VALUE (f->neighbor, GFS_BC_FLATHER (b)->p) - pb)*
+      cg/sim->physical_params.g
+#if !FTT_2D
+      /H
+#endif
+      ;
+  }
+  else
+    return 0.;
+}
+
+static void flather (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  GFS_VARIABLE (f->cell, b->v->i) = 2.*flather_value (f, b) - GFS_VARIABLE (f->neighbor, b->v->i);
+}
+
+static void homogeneous_flather (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  GFS_VARIABLE (f->cell, b->v->i) = - GFS_VARIABLE (f->neighbor, b->v->i);
+}
+
+static void face_flather (FttCellFace * f, GfsBc * b)
+{
+  g_assert (GFS_CELL_IS_GRADIENT_BOUNDARY (f->cell));
+  GFS_STATE (f->cell)->f[f->d].v = flather_value (f, b);
+}
+
+static void gfs_bc_flather_class_init (GtsObjectClass * klass)
+{
+  klass->write   = bc_flather_write;
+  klass->read    = bc_flather_read;
+  klass->destroy = bc_flather_destroy;
+}
+
+static void gfs_bc_flather_init (GfsBc * object)
+{
+  object->bc =             (FttFaceTraverseFunc) flather;
+  object->homogeneous_bc = (FttFaceTraverseFunc) homogeneous_flather;
+  object->face_bc =        (FttFaceTraverseFunc) face_flather;
+}
+
+GfsBcClass * gfs_bc_flather_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_flather_info = {
+      "GfsBcFlather",
+      sizeof (GfsBcFlather),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_flather_class_init,
+      (GtsObjectInitFunc) gfs_bc_flather_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_flather_info);
+  }
+
+  return klass;
+}
diff --git a/src/ocean.h b/src/ocean.h
new file mode 100644
index 0000000..5c5b561
--- /dev/null
+++ b/src/ocean.h
@@ -0,0 +1,129 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2004 Stéphane Popinet
+ * National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __OCEAN_H__
+#define __OCEAN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "simulation.h"
+#include "source.h"
+
+/* GfsOcean: Header */
+
+typedef struct _GfsOcean         GfsOcean;
+
+struct _GfsOcean {
+  GfsSimulation parent;
+#if !FTT_2D
+  GPtrArray * layer;
+  GfsDomain * toplayer;
+#endif /* 2D3 or 3D */
+};
+
+#define GFS_OCEAN(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOcean,\
+					         gfs_ocean_class ())
+#define GFS_IS_OCEAN(obj)         (gts_object_is_from_class (obj,\
+						 gfs_ocean_class ()))
+
+GfsSimulationClass * gfs_ocean_class          (void);
+
+#if !FTT_2D
+
+void                 gfs_hydrostatic_pressure (GfsDomain * domain,
+					       GfsVariable * p,
+					       GfsVariable * rho,
+					       gdouble g);
+
+/* GfsSourceHydrostatic: Header */
+
+typedef struct _GfsSourceHydrostatic         GfsSourceHydrostatic;
+
+struct _GfsSourceHydrostatic {
+  /*< private >*/
+  GfsSourceVelocity parent;
+  GfsVariable * ph1;
+  gboolean not_first;
+
+  /*< public >*/
+  GfsVariable * ph, * rho;
+};
+
+#define GFS_SOURCE_HYDROSTATIC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceHydrostatic,\
+					         gfs_source_hydrostatic_class ())
+#define GFS_IS_SOURCE_HYDROSTATIC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_hydrostatic_class ()))
+
+GfsSourceGenericClass * gfs_source_hydrostatic_class    (void);
+
+#endif /* 2D3 or 3D */
+
+/* GfsSourceFriction: Header */
+
+typedef struct _GfsSourceFriction         GfsSourceFriction;
+
+struct _GfsSourceFriction {
+  /*< private >*/
+  GfsSourceVelocity parent;
+  GfsVariable * u[FTT_DIMENSION];
+
+  /*< public >*/
+  GfsVariable * h;
+  gdouble f;
+};
+
+#define GFS_SOURCE_FRICTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceFriction,\
+					         gfs_source_friction_class ())
+#define GFS_IS_SOURCE_FRICTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_friction_class ()))
+
+GfsSourceGenericClass * gfs_source_friction_class  (void);
+
+/* GfsBcFlather: Header */
+
+typedef struct _GfsBcFlather         GfsBcFlather;
+
+struct _GfsBcFlather {
+  /*< private >*/
+  GfsBcValue parent;
+
+  /*< public >*/
+  GfsVariable * h, * p;
+  GfsFunction * val;
+};
+
+#define GFS_BC_FLATHER(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsBcFlather,\
+					         gfs_bc_flather_class ())
+#define GFS_IS_BC_FLATHER(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_flather_class ()))
+
+GfsBcClass * gfs_bc_flather_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __OCEAN_H__ */
diff --git a/src/output.c b/src/output.c
new file mode 100644
index 0000000..630a1cc
--- /dev/null
+++ b/src/output.c
@@ -0,0 +1,3157 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+#include <math.h>
+#include "output.h"
+#include "graphic.h"
+#include "adaptive.h"
+#include "solid.h"
+#include "ocean.h"
+#include "unstructured.h"
+
+/* GfsOutput: object */
+
+typedef struct _Format Format;
+
+typedef enum {
+  ITER,
+  TIME,
+  PID,
+  NONE
+} FormatType;
+
+struct _Format {
+  gchar * s;
+  FormatType t;
+};
+
+static Format * format_new (gchar * s, guint len, 
+			    FormatType t)
+{
+  Format * f = g_malloc (sizeof (Format));
+  
+  f->s = g_strndup (s, len);
+  f->t = t;
+
+  return f;
+}
+
+static void format_destroy (Format * f)
+{
+  g_free (f->s);
+  g_free (f);
+}
+
+static gchar * format_string (GSList * list, 
+			      gint pid, 
+			      guint niter,
+			      gdouble time)
+{
+  gchar * s = g_strdup ("");
+
+  while (list) {
+    Format * f = list->data;
+    gchar * s1, * s2 = NULL;
+
+    switch (f->t) {
+    case NONE:
+      s2 = g_strconcat (s, f->s, NULL);
+      break;
+    case PID:
+      s1 = g_strdup_printf (f->s, pid);
+      s2 = g_strconcat (s, s1, NULL);
+      g_free (s1);
+      break;
+    case ITER:
+      s1 = g_strdup_printf (f->s, niter);
+      s2 = g_strconcat (s, s1, NULL);
+      g_free (s1);
+      break;
+    case TIME:
+      s1 = g_strdup_printf (f->s, time);
+      s2 = g_strconcat (s, s1, NULL);
+      g_free (s1);
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+    g_free (s);
+    s = s2;
+    list = list->next;
+  }
+
+  return s;
+}
+
+static void output_free (GfsOutput * output)
+{
+  if (output->format)
+    g_free (output->format);
+  output->format = NULL;
+  g_slist_foreach (output->formats, (GFunc) format_destroy, NULL);
+  g_slist_free (output->formats);
+  output->formats = NULL;
+}
+
+static void gfs_output_destroy (GtsObject * object)
+{
+  GfsOutput * output = GFS_OUTPUT (object);
+
+  if (output->file)
+    gfs_output_file_close (output->file);
+  output_free (output);
+
+  (* GTS_OBJECT_CLASS (gfs_output_class ())->parent_class->destroy) 
+    (object);
+}
+
+static gboolean gfs_output_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* gfs_event_class ()->event) (event, sim)) {
+    GfsOutput * output = GFS_OUTPUT (event);
+    gchar * fname;
+
+    if (!output->parallel && GFS_DOMAIN (sim)->pid > 0) {
+      if (output->file)
+	output->first_call = FALSE;
+      else
+	gfs_output_mute (output);
+      return (output->file != NULL);
+    }
+
+    if (!output->dynamic) {
+      if (output->file) {
+	fflush (output->file->fp);
+	output->first_call = FALSE;
+      }
+      else {
+	if (output->format[0] == '{') { /* script */
+	  guint len = strlen (output->format);
+	  g_assert (output->format[len - 1] == '}');
+	  output->format[len - 1] = '\0';
+	  FILE * fp = gfs_popen (sim, &output->format[1], "w");
+	  if (fp == NULL) {
+	    g_warning ("GfsOutput cannot start script");
+	    return TRUE;
+	  }
+	  output->file = gfs_output_file_new (fp);
+	  output->file->is_pipe = TRUE;
+	  output->format[len - 1] = '}';
+	}
+	else { /* standard file */
+	  fname = format_string (output->formats,
+				 GFS_DOMAIN (sim)->pid,
+				 sim->time.i,
+				 sim->time.t);
+	  output->file = gfs_output_file_open (fname, 
+					       sim->time.i > 0 && gfs_event_is_repetitive (event) ? 
+					       "a" : "w");
+	  if (output->file == NULL)
+	    g_warning ("could not open file `%s'", fname);
+	  g_free (fname);
+	}
+      }
+      return (output->file != NULL);
+    }
+
+    if (output->file)
+      gfs_output_file_close (output->file);
+    fname = format_string (output->formats, 
+			   GFS_DOMAIN (sim)->pid,
+			   sim->time.i,
+			   sim->time.t);
+    output->file = gfs_output_file_open (fname, "w");
+    if (output->file == NULL)
+      g_warning ("could not open file `%s'", fname);
+    g_free (fname);
+    return (output->file != NULL);
+  }
+  return FALSE;
+}
+
+static void gfs_output_write (GtsObject * o, FILE * fp)
+{
+  GfsOutput * output = GFS_OUTPUT (o);
+
+  (* GTS_OBJECT_CLASS (gfs_output_class ())->parent_class->write) (o, fp);
+
+  if (output->format)
+    fprintf (fp, " %s", output->format);
+}
+
+static void gfs_output_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutput * output;
+
+  (* GTS_OBJECT_CLASS (gfs_output_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  output = GFS_OUTPUT (*o);
+  if (output->file)
+    gfs_output_file_close (output->file);
+  output->file = NULL;
+  if (output->format)
+    g_free (output->format);
+  output->format = NULL;
+  output->dynamic = FALSE;
+  output->first_call = TRUE;
+
+  if (fp->type == '{') {
+    gchar * script = gfs_file_statement (fp);
+    if (script == NULL)
+      return;
+    output->format = g_strconcat ("{", script, "}", NULL);
+    g_free (script);
+    gts_file_next_token (fp);
+  }
+  else if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (format)");
+    return;
+  }
+  else {
+    GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (output));
+    gchar * c, * start;
+    guint len;
+
+    output->format = g_strdup (fp->token->str);
+    gts_file_next_token (fp);
+    
+    if (!strcmp (output->format, "stderr") || !strcmp (output->format, "stdout")) {
+      if (domain->pid > 0)
+	gfs_output_mute (output);
+      else {
+	g_assert (!output->file);
+	output->file = gfs_output_file_open (output->format, "w");
+      }
+      return;
+    }
+    
+    start = c = output->format;
+    while (*c != '\0') {
+      if (*c == '%') {
+	gchar * startf = c, * prev = c;
+	
+	len = GPOINTER_TO_UINT (startf) -  GPOINTER_TO_UINT (start);
+	if (len > 0)
+	  output->formats = g_slist_prepend (output->formats,
+					     format_new (start, len, NONE));
+	
+	len = 1;
+	c++;
+	while (*c != '\0' && !gfs_char_in_string (*c, "diouxXeEfFgGaAcsCSpn%")) {
+	  prev = c;
+	  c++;
+	  len++;
+	}
+	len++;
+	if (*c == '%')
+	  output->formats = g_slist_prepend (output->formats,
+					     format_new ("%", 1, NONE));
+	else if (gfs_char_in_string (*c, "diouxXc")) {
+	  if (*prev == 'l') {
+	    output->formats = g_slist_prepend (output->formats,
+					       format_new (startf, len, ITER));
+	    output->dynamic = TRUE;
+	  }
+	  else {
+	    output->formats = g_slist_prepend (output->formats,
+					       format_new (startf, len, PID));
+	    output->parallel = TRUE;
+	  }
+	}
+	else if (gfs_char_in_string (*c, "eEfFgGaA")) {
+	  output->formats = g_slist_prepend (output->formats,
+					     format_new (startf, len, TIME));
+	  output->dynamic = TRUE;
+	}
+	else {
+	  gts_file_error (fp, 
+			  "unknown conversion specifier `%c' of format `%s'",
+			  *c, output->format);
+	  output_free (output);
+	  return;
+	}
+	start = c;
+	start++;
+      }
+      c++;
+    }
+    len = GPOINTER_TO_UINT (c) - GPOINTER_TO_UINT (start);
+    if (len > 0)
+      output->formats = g_slist_prepend (output->formats,
+					 format_new (start, len, NONE));
+    output->formats = g_slist_reverse (output->formats);
+
+    if (output->parallel || domain->pid <= 0) {
+      gchar * fname = format_string (output->formats, domain->pid, 0, 0.);
+      gchar * fnamebak = g_strconcat (fname, "~", NULL);
+      g_free (fname);
+      FILE * fptr = fopen (fnamebak, "w");
+      if (fptr == NULL) {
+	gts_file_error (fp, "cannot open file specified by format `%s'\n  %s",
+			output->format, strerror (errno));
+	g_free (fnamebak);
+	output_free (output);
+	return;
+      }
+      fclose (fptr);
+      remove (fnamebak);
+      g_free (fnamebak);
+    }
+  }
+}
+
+static void gfs_output_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_event;
+
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_write;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_read;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_destroy;
+}
+
+static void gfs_output_init (GfsOutput * object)
+{
+  object->file = NULL;
+  object->format = NULL;
+  object->formats = NULL;
+  object->dynamic = FALSE;
+  object->parallel = FALSE;
+  object->first_call = TRUE;
+}
+
+GfsOutputClass * gfs_output_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_info = {
+      "GfsOutput",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_class_init,
+      (GtsObjectInitFunc) gfs_output_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_output_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_output_mute:
+ * @output: a #GfsOutput.
+ *
+ * "Mutes" the output defined by @output, the event associated with
+ * @output still takes place but the output itself is redirected to
+ * /dev/null.
+ */
+void gfs_output_mute (GfsOutput * output)
+{
+  g_return_if_fail (output != NULL);
+
+  output->dynamic = FALSE;
+  if (output->file)
+    gfs_output_file_close (output->file);
+  output->file = gfs_output_file_open ("/dev/null", "w");
+}
+
+static GHashTable * gfs_output_files = NULL;
+
+/**
+ * gfs_output_file_new:
+ * @fp: a file pointer.
+ *
+ * Returns: a new #GfsOutputFile for @fp.
+ */
+GfsOutputFile * gfs_output_file_new (FILE * fp)
+{
+  GfsOutputFile * file = g_malloc (sizeof (GfsOutputFile));
+  file->refcount = 1;
+  file->name = NULL;
+  file->fp = fp;
+  file->is_pipe = FALSE;
+  return file;
+}
+
+/**
+ * gfs_output_file_open:
+ * @name: the name of the file to open.
+ * @mode: the fopen mode.
+ *
+ * Checks whether @name has already been opened. If it has, its
+ * reference count is incremented and the corresponding #GfsOutputFile
+ * is returned. If it has not, it is created and opened for writing.
+ *
+ * Returns: the #GfsOutputFile of file @name.  
+ */
+GfsOutputFile * gfs_output_file_open (const gchar * name, const gchar * mode)
+{
+  GfsOutputFile * file;
+  FILE * fp;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  if (gfs_output_files == NULL) {
+    gfs_output_files = g_hash_table_new (g_str_hash, g_str_equal);
+    file = g_malloc (sizeof (GfsOutputFile));
+    file->refcount = 2;
+    file->name = g_strdup ("stderr");
+    file->fp = stderr;
+    g_hash_table_insert (gfs_output_files, file->name, file);
+    file = g_malloc (sizeof (GfsOutputFile));
+    file->refcount = 2;
+    file->name = g_strdup ("stdout");
+    file->fp = stdout;
+    g_hash_table_insert (gfs_output_files, file->name, file);
+  }
+
+  if ((file = g_hash_table_lookup (gfs_output_files, name))) {
+    file->refcount++;
+    return file;
+  }
+
+  fp = fopen (name, mode);
+  if (fp == NULL)
+    return NULL;
+
+  file = gfs_output_file_new (fp);
+  file->name = g_strdup (name);
+  g_hash_table_insert (gfs_output_files, file->name, file);
+
+  return file;  
+}
+
+/**
+ * gfs_output_file_close:
+ * @file: a #GfsOutputFile.
+ * 
+ * Decreases the reference count of @file. If it reaches zero the file
+ * corresponding to @file is closed and @file is freed.
+ */
+void gfs_output_file_close (GfsOutputFile * file)
+{
+  g_return_if_fail (file);
+
+  file->refcount--;
+  if (file->refcount == 0) {
+    if (file->name)
+      g_hash_table_remove (gfs_output_files, file->name);
+    if (file->is_pipe)
+      pclose (file->fp);
+    else
+      fclose (file->fp);
+    g_free (file->name);
+    g_free (file);
+  }
+}
+
+/* GfsOutputTime: Object */
+
+static void time_destroy (GtsObject * o)
+{
+  gfs_clock_destroy (GFS_OUTPUT_TIME (o)->clock);
+  g_timer_destroy (GFS_OUTPUT_TIME (o)->timer);
+
+  (* GTS_OBJECT_CLASS (gfs_output_time_class ())->parent_class->destroy) (o);  
+}
+
+static gboolean time_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    GfsOutputTime * t = GFS_OUTPUT_TIME (event);
+    if (!t->clock->started) {
+      gfs_clock_start (t->clock);
+      g_timer_start (t->timer);
+    }
+    gdouble cpu = gfs_clock_elapsed (t->clock);
+#ifdef HAVE_MPI
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    if (domain->pid >= 0) {
+      gfs_all_reduce (domain, cpu, MPI_DOUBLE, MPI_SUM);
+      int size;
+      MPI_Comm_size (MPI_COMM_WORLD, &size);
+      cpu /= size;
+    }
+#endif
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "step: %7u t: %15.8f dt: %13.6e cpu: %15.8f real: %15.8f\n",
+	     sim->time.i, sim->time.t, 
+	     sim->advection_params.dt,
+	     cpu,
+	     g_timer_elapsed (t->timer, NULL));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_time_class_init (GfsEventClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = time_destroy;
+  klass->event = time_event;
+}
+
+static void gfs_output_time_init (GfsOutputTime * time)
+{
+  time->clock = gfs_clock_new ();
+  time->timer = g_timer_new ();
+}
+
+GfsOutputClass * gfs_output_time_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_time_info = {
+      "GfsOutputTime",
+      sizeof (GfsOutputTime),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_time_class_init,
+      (GtsObjectInitFunc) gfs_output_time_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_time_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputProgress: Object */
+
+static gboolean progress_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    gdouble idone = sim->time.i/(gdouble) sim->time.iend;
+    gdouble tdone = sim->time.t/sim->time.end;
+
+    if (idone > tdone) tdone = idone;
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "\r%3.0f%% done",
+	     100.*tdone);
+    if (tdone > 0.) {
+      gdouble remaining = GFS_DOMAIN (sim)->timestep.sum*(1. - tdone)/tdone;
+      gdouble hours = floor (remaining/3600.);
+      gdouble mins = floor ((remaining - 3600.*hours)/60.);
+      gdouble secs = floor (remaining - 3600.*hours - 60.*mins);
+      fprintf (GFS_OUTPUT (event)->file->fp,
+	       ", %02.0f:%02.0f:%02.0f remaining ",
+	       hours, mins, secs);
+    }
+    if (tdone == 1.)
+      fputc ('\n', GFS_OUTPUT (event)->file->fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_progress_class_init (GfsEventClass * klass)
+{
+  klass->event = progress_event;
+}
+
+GfsOutputClass * gfs_output_progress_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_progress_info = {
+      "GfsOutputProgress",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_progress_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_progress_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputProjectionStats: Object */
+
+static gboolean projection_stats_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+
+    if (sim->projection_params.niter > 0) {
+      fprintf (fp, "MAC projection        before     after       rate\n");
+      gfs_multilevel_params_stats_write (&sim->projection_params, fp);
+    }
+    fprintf (fp, "Approximate projection\n");
+    gfs_multilevel_params_stats_write (&sim->approx_projection_params, fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_projection_stats_class_init (GfsEventClass * klass)
+{
+  klass->event = projection_stats_event;
+}
+
+GfsOutputClass * gfs_output_projection_stats_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_projection_stats_info = {
+      "GfsOutputProjectionStats",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_projection_stats_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_projection_stats_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputDiffusionStats: Object */
+
+static gboolean diffusion_stats_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    GSList * l = NULL, * i;
+    
+    i = GFS_DOMAIN (sim)->variables;
+    while (i) {
+      GfsVariable * v = i->data;
+
+      if (v->sources) {
+	GSList * j = GTS_SLIST_CONTAINER (v->sources)->items;
+    
+	while (j) {
+	  GtsObject * o = j->data;
+      
+	  if (GFS_IS_SOURCE_DIFFUSION (o) && !g_slist_find (l, o)) {
+	    l = g_slist_prepend (l, o);
+	    fprintf (fp, "%s diffusion\n", v->name);
+	    gfs_multilevel_params_stats_write (&GFS_SOURCE_DIFFUSION (o)->D->par, fp);
+	  }
+	  j = j->next;
+	}
+      }
+      i = i->next;
+    }
+    g_slist_free (l);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_diffusion_stats_class_init (GfsEventClass * klass)
+{
+  klass->event = diffusion_stats_event;
+}
+
+GfsOutputClass * gfs_output_diffusion_stats_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_diffusion_stats_info = {
+      "GfsOutputDiffusionStats",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_diffusion_stats_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_diffusion_stats_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputSolidStats: Object */
+
+static gboolean gfs_output_solid_stats_event (GfsEvent * event, 
+					     GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_solid_stats_class ())->parent_class)->event)
+      (event, sim)) {
+    GtsRange stats = gfs_domain_stats_solid (GFS_DOMAIN (sim));
+    GtsRange ma, mn;
+
+    gfs_domain_stats_merged (GFS_DOMAIN (sim), &ma, &mn);
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "Solid volume fraction\n"
+	     "    min: %10.3e avg: %10.3e | %10.3e max: %10.3e n: %10d\n"
+	     "Total merged solid volume fraction\n"
+	     "    min: %10.3e avg: %10.3e | %10.3e max: %10.3e n: %10d\n"
+	     "Number of cells merged per merged cell\n"
+	     "    min: %10.0f avg: %10.3f | %10.3f max: %10.0f n: %10d\n"
+	     "Number of \"thin\" cells removed: %10d\n",
+	     stats.min, stats.mean, stats.stddev, stats.max, stats.n,
+	     ma.min, ma.mean, ma.stddev, ma.max, ma.n,
+	     mn.min, mn.mean, mn.stddev, mn.max, mn.n,
+	     sim->thin);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_solid_stats_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_solid_stats_event;
+}
+
+GfsOutputClass * gfs_output_solid_stats_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_solid_stats_info = {
+      "GfsOutputSolidStats",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_solid_stats_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_solid_stats_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputAdaptStats: Object */
+
+static gboolean gfs_output_adapt_stats_event (GfsEvent * event, 
+					      GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_adapt_stats_class ())->parent_class)->event)
+      (event, sim)) {
+    gfs_adapt_stats_update (&sim->adapts_stats);
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "Adaptive mesh refinement statistics\n"
+	     "  Cells removed: %10d\n"
+	     "  Cells created: %10d\n"
+	     "  Number of cells\n"
+	     "    min: %10.0f avg: %10.3f | %10.3f max: %10.0f n: %10d\n",
+	     sim->adapts_stats.removed,
+	     sim->adapts_stats.created,
+	     sim->adapts_stats.ncells.min,
+	     sim->adapts_stats.ncells.mean,
+	     sim->adapts_stats.ncells.stddev,
+	     sim->adapts_stats.ncells.max,
+	     sim->adapts_stats.ncells.n);
+    if (sim->adapts_stats.cmax.n > 0)
+      fprintf (GFS_OUTPUT (event)->file->fp,
+	       "  Maximum cost\n"
+	       "    min: %10.3e avg: %10.3e | %10.3e max: %10.3e n: %10d\n",
+	       sim->adapts_stats.cmax.min,
+	       sim->adapts_stats.cmax.mean,
+	       sim->adapts_stats.cmax.stddev,
+	       sim->adapts_stats.cmax.max,
+	       sim->adapts_stats.cmax.n);
+    gfs_adapt_stats_init (&sim->adapts_stats);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_adapt_stats_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_adapt_stats_event;
+}
+
+GfsOutputClass * gfs_output_adapt_stats_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_adapt_stats_info = {
+      "GfsOutputAdaptStats",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_adapt_stats_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_adapt_stats_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputTiming: Object */
+
+typedef struct {
+  GfsTimer * t;
+  gchar * name;
+} Timer;
+
+static int compare_timer (const void * a, const void * b)
+{
+  Timer * t1 = (Timer *) a;
+  Timer * t2 = (Timer *) b;
+  return (t1->t->r.sum < t2->t->r.sum) ? -1 : 1 ;
+}
+
+static void get_timer (gchar * name, GfsTimer * t, gpointer * data)
+{
+  Timer * timing = data[0];
+  gint * count = data[1];
+  timing[*count].t = t;
+  timing[*count].name = name;
+  (*count)++;
+}
+
+static void print_timing (GHashTable * timers, GfsDomain * domain, FILE * fp)
+{
+  Timer * timing = g_malloc (sizeof (Timer)*g_hash_table_size (timers));
+  gint count = 0;
+  gpointer data[2];
+
+  data[0] = timing;
+  data[1] = &count;  
+  g_hash_table_foreach (domain->timers, (GHFunc) get_timer, data);
+  qsort (timing, count, sizeof (Timer), compare_timer);
+  while (--count >= 0)
+    if (timing[count].t->r.sum > 0.)
+      fprintf (fp, 
+	       "  %s:\n"
+	       "      min: %9.3f avg: %9.3f (%4.1f%%) | %7.3f max: %9.3f\n",
+	       timing[count].name,
+	       timing[count].t->r.min,
+	       timing[count].t->r.mean, 
+	       domain->timestep.sum > 0. ? 100.*timing[count].t->r.sum/domain->timestep.sum : 0.,
+	       timing[count].t->r.stddev, 
+	       timing[count].t->r.max);
+  g_free (timing);
+}
+
+static gboolean timing_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    
+    if (domain->timestep.mean > 0.) {
+      fprintf (fp,
+	       "Timing summary: %u timesteps %.0f node.timestep/s\n"
+	       "  timestep:\n"
+	       "      min: %9.3f avg: %9.3f         | %7.3f max: %9.3f\n"
+               "  domain size:\n"
+	       "      min: %9.0f avg: %9.0f         | %7.0f max: %9.0f\n"
+	       "  maximum number of variables: %d\n",
+	       domain->timestep.n,
+	       domain->size.mean/domain->timestep.mean,
+	       domain->timestep.min,
+	       domain->timestep.mean,
+	       domain->timestep.stddev, 
+	       domain->timestep.max,
+	       domain->size.min,
+	       domain->size.mean,
+	       domain->size.stddev, 
+	       domain->size.max,
+	       gfs_domain_variables_number (domain));
+      print_timing (domain->timers, domain, fp);
+      if (domain->mpi_messages.n > 0)
+	fprintf (fp,
+		 "Message passing summary\n"
+		 "  n: %10d size: %10.0f bytes\n",
+		 domain->mpi_messages.n,
+		 domain->mpi_messages.sum);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_timing_class_init (GfsEventClass * klass)
+{
+  klass->event = timing_event;
+}
+
+GfsOutputClass * gfs_output_timing_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_timing_info = {
+      "GfsOutputTiming",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_timing_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_timing_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputBalance: Object */
+
+static gboolean gfs_output_balance_event (GfsEvent * event, 
+					  GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_balance_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    GtsRange size, boundary, mpiwait;
+    
+    gfs_domain_stats_balance (domain, &size, &boundary, &mpiwait);
+    fprintf (fp, 
+	     "Balance summary: %u PE\n"
+	     "  domain   min: %9.0f avg: %9.0f         | %7.0f max: %9.0f\n",
+	     size.n,
+	     size.min, size.mean, size.stddev, size.max);
+    if (boundary.max > 0.)
+      fprintf (fp, 
+	       "  boundary min: %9.0f avg: %9.0f         | %7.0f max: %9.0f\n",
+	       boundary.min, boundary.mean, boundary.stddev, boundary.max);
+    if (mpiwait.max > 0.)
+      fprintf (fp,
+	       "  average timestep MPI wait time:\n"
+	       "      min: %9.3f avg: %9.3f         | %7.3f max: %9.3f\n",
+	       mpiwait.min, mpiwait.mean, mpiwait.stddev, mpiwait.max);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_balance_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_balance_event;
+}
+
+GfsOutputClass * gfs_output_balance_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_balance_info = {
+      "GfsOutputBalance",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_balance_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_balance_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputSolidForce: Object */
+
+static void gfs_output_solid_force_destroy (GtsObject * object)
+{
+  if (GFS_OUTPUT_SOLID_FORCE (object)->weight)
+    gts_object_destroy (GTS_OBJECT (GFS_OUTPUT_SOLID_FORCE (object)->weight));
+
+  (* GTS_OBJECT_CLASS (gfs_output_solid_force_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_output_solid_force_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputSolidForce * l = GFS_OUTPUT_SOLID_FORCE (*o);
+
+  (* GTS_OBJECT_CLASS (gfs_output_solid_force_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != '\n') {
+    if (!l->weight)
+      l->weight = gfs_function_new (gfs_function_class (), 0.);
+    gfs_function_read (l->weight, gfs_object_simulation (l), fp);
+  }
+}
+
+static void gfs_output_solid_force_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputSolidForce * l = GFS_OUTPUT_SOLID_FORCE (o);
+  (* GTS_OBJECT_CLASS (gfs_output_solid_force_class ())->parent_class->write) (o, fp);
+  if (l->weight)
+    gfs_function_write (l->weight, fp);
+}
+
+static gboolean gfs_output_solid_force_event (GfsEvent * event, 
+					      GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_solid_force_class ())->parent_class)->event)
+      (event, sim) &&
+      sim->advection_params.dt > 0.) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    FttVector pf, vf, pm, vm;
+    gdouble L = sim->physical_params.L, Ln = pow (L, 3. + FTT_DIMENSION - 2.);
+
+    if (GFS_OUTPUT (event)->first_call)
+      fputs ("# 1: T (2,3,4): Pressure force (5,6,7): Viscous force "
+	     "(8,9,10): Pressure moment (11,12,13): Viscous moment\n", fp);
+    
+    gfs_domain_solid_force (domain, &pf, &vf, &pm, &vm, GFS_OUTPUT_SOLID_FORCE (event)->weight);
+    fprintf (fp, "%g %g %g %g %g %g %g %g %g %g %g %g %g\n",
+	     sim->time.t,
+	     pf.x*Ln, pf.y*Ln, pf.z*Ln,
+	     vf.x*Ln, vf.y*Ln, vf.z*Ln,
+	     pm.x*Ln*L, pm.y*Ln*L, pm.z*Ln*L,
+	     vm.x*Ln*L, vm.y*Ln*L, vm.z*Ln*L);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_solid_force_class_init (GfsOutputClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_solid_force_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_solid_force_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_solid_force_destroy;
+  GFS_EVENT_CLASS (klass)->event = gfs_output_solid_force_event;
+}
+
+GfsOutputClass * gfs_output_solid_force_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_solid_force_info = {
+      "GfsOutputSolidForce",
+      sizeof (GfsOutputSolidForce),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_solid_force_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_solid_force_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputLocation: Object */
+
+static void gfs_output_location_destroy (GtsObject * object)
+{
+  g_array_free (GFS_OUTPUT_LOCATION (object)->p, TRUE);
+
+  (* GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class->destroy) (object);
+}
+
+static gboolean vector_read (GtsFile * fp, FttVector * p)
+{
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.x)");
+    return FALSE;
+  }
+  p->x = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.y)");
+    return FALSE;
+  }
+  p->y = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.z)");
+    return FALSE;
+  }
+  p->z = atof (fp->token->str);
+  gts_file_next_token (fp);
+  return TRUE;
+}
+
+static void gfs_output_location_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputLocation * l = GFS_OUTPUT_LOCATION (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type == GTS_STRING) {
+    FILE * fptr = fopen (fp->token->str, "r");
+    GtsFile * fp1;
+
+    if (fptr == NULL) {
+      gts_file_error (fp, "cannot open file `%s'", fp->token->str);
+      return;
+    }
+    fp1 = gts_file_new (fptr);
+    while (fp1->type != GTS_NONE) {
+      FttVector p;
+      if (!vector_read (fp1, &p)) {
+	gts_file_error (fp, "%s:%d:%d: %s", fp->token->str, fp1->line, fp1->pos, fp1->error);
+	return;
+      }
+      g_array_append_val (l->p, p);
+      while (fp1->type == '\n')
+	gts_file_next_token (fp1);
+    }
+    gts_file_destroy (fp1);
+    fclose (fptr);
+    gts_file_next_token (fp);
+  }
+  else if (fp->type == '{') {
+    fp->scope_max++;
+    do
+      gts_file_next_token (fp);
+    while (fp->type == '\n');
+    while (fp->type != GTS_NONE && fp->type != '}') {
+      FttVector p;
+      if (!vector_read (fp, &p))
+	return;
+      g_array_append_val (l->p, p);
+      while (fp->type == '\n')
+	gts_file_next_token (fp);
+    }
+    if (fp->type != '}') {
+      gts_file_error (fp, "expecting a closing brace");
+      return;
+    }
+    fp->scope_max--;
+    gts_file_next_token (fp);
+  }
+  else {
+    FttVector p;
+    if (!vector_read (fp, &p))
+      return;
+    g_array_append_val (l->p, p);
+  }
+}
+
+static void gfs_output_location_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputLocation * l = GFS_OUTPUT_LOCATION (o);
+  guint i;
+
+  (* GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class->write) (o, fp);
+
+  fputs (" {\n", fp);
+  for (i = 0; i < l->p->len; i++) {
+    FttVector p = g_array_index (l->p, FttVector, i);
+    fprintf (fp, "%g %g %g\n", p.x, p.y, p.z);
+  }
+  fputc ('}', fp);
+}
+
+static gboolean gfs_output_location_event (GfsEvent * event, 
+					   GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsOutputLocation * location = GFS_OUTPUT_LOCATION (event);
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    guint i;
+
+    if (GFS_OUTPUT (event)->first_call) {
+      GSList * i = domain->variables;
+      guint nv = 5;
+
+      fputs ("# 1:T 2:X 3:Y 4:Z", fp);
+      while (i) {
+	if (GFS_VARIABLE1 (i->data)->name)
+	  fprintf (fp, " %d:%s", nv++, GFS_VARIABLE1 (i->data)->name);
+	i = i->next;
+      }
+      fputc ('\n', fp);
+    }
+    for (i = 0; i < location->p->len; i++) {
+      FttVector p = g_array_index (location->p, FttVector, i), pm = p;
+      gfs_simulation_map (sim, &pm);
+      FttCell * cell = gfs_domain_locate (domain, pm, -1, NULL);
+      
+      if (cell != NULL) {
+	GSList * i = domain->variables;
+	
+	fprintf (fp, "%g %g %g %g", sim->time.t, p.x, p.y, p.z);
+	while (i) {
+	  GfsVariable * v = i->data;
+	  if (v->name)
+	    fprintf (fp, " %g", gfs_dimensional_value (v, gfs_interpolate (cell, pm, v)));
+	  i = i->next;
+	}
+	fputc ('\n', fp);
+      }
+    }
+    fflush (fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_location_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_location_event;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_location_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_location_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_location_write;
+}
+
+static void gfs_output_location_init (GfsOutputLocation * object)
+{
+  object->p = g_array_new (FALSE, FALSE, sizeof (FttVector));
+}
+
+GfsOutputClass * gfs_output_location_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_location_info = {
+      "GfsOutputLocation",
+      sizeof (GfsOutputLocation),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_location_class_init,
+      (GtsObjectInitFunc) gfs_output_location_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_location_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputSimulation: Object */
+
+static gchar default_precision[] = "%g";
+
+static void output_simulation_destroy (GtsObject * object)
+{
+  GfsOutputSimulation * output = GFS_OUTPUT_SIMULATION (object);
+
+  g_slist_free (output->var);
+  if (output->precision != default_precision)
+    g_free (output->precision);
+
+  (* GTS_OBJECT_CLASS (gfs_output_simulation_class ())->parent_class->destroy) (object);
+}
+
+static void write_text (FttCell * cell, gpointer * data)
+{
+  GfsOutputSimulation * output = data[0];  
+  FILE * fp = data[1];
+  GSList * i = GFS_DOMAIN (gfs_object_simulation (output))->variables_io;
+  FttVector p;
+
+  gfs_cell_cm (cell, &p);
+  gfs_simulation_map_inverse (gfs_object_simulation (output), &p);
+  gchar * format = g_strdup_printf ("%s %s %s", 
+				    output->precision, output->precision, output->precision);
+  fprintf (fp, format, p.x, p.y, p.z);
+  g_free (format);
+  format = g_strdup_printf (" %s", output->precision);
+  while (i) {
+    if (GFS_VARIABLE1 (i->data)->name)
+      fprintf (fp, format, gfs_dimensional_value (i->data, 
+						  GFS_VALUE (cell, GFS_VARIABLE1 (i->data))));
+    i = i->next;
+  }
+  g_free (format);
+  fputc ('\n', fp);
+}
+
+static gboolean output_simulation_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsOutputSimulation * output = GFS_OUTPUT_SIMULATION (event);
+
+    g_slist_free (domain->variables_io);
+    if (output->var)
+      domain->variables_io = output->var;
+    else {
+      GSList * i = domain->variables;
+      domain->variables_io = NULL;
+      while (i) {
+	if (GFS_VARIABLE1 (i->data)->name)
+	  domain->variables_io = g_slist_append (domain->variables_io, i->data);
+	i = i->next;
+      }
+    }
+
+    domain->binary =       output->binary;
+    sim->output_solid   =  output->solid;
+    switch (output->format) {
+
+    case GFS:
+      if (GFS_OUTPUT (output)->parallel)
+	gfs_simulation_write (sim,
+			      output->max_depth,
+			      GFS_OUTPUT (event)->file->fp);
+      else
+	gfs_simulation_union_write (sim,
+				    output->max_depth,
+				    GFS_OUTPUT (event)->file->fp);
+      break;
+
+    case GFS_TEXT: {
+      if (GFS_OUTPUT (output)->parallel || domain->pid <= 0) {
+	FILE * fp = GFS_OUTPUT (event)->file->fp;
+	GSList * i = domain->variables_io;
+	guint nv = 4;
+
+	fputs ("# 1:X 2:Y 3:Z", fp);
+	while (i) {
+	  g_assert (GFS_VARIABLE1 (i->data)->name);
+	  fprintf (fp, " %d:%s", nv++, GFS_VARIABLE1 (i->data)->name);
+	  i = i->next;
+	}
+	fputc ('\n', fp);
+      }
+      gpointer data[2];
+      data[0] = output;
+      if (GFS_OUTPUT (output)->parallel) {
+	data[1] = GFS_OUTPUT (event)->file->fp;
+	gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) write_text, data);
+      }
+      else {
+	FILE * fpp = gfs_union_open (GFS_OUTPUT (event)->file->fp, domain->pid);
+	data[1] = fpp;
+	gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) write_text, data);
+	gfs_union_close (GFS_OUTPUT (event)->file->fp, domain->pid, fpp);
+      }
+      break;
+    }
+
+    case GFS_VTK: {
+      gfs_domain_write_vtk (domain, output->max_depth, domain->variables_io, output->precision,
+			    GFS_OUTPUT (event)->file->fp);
+      break;
+    }
+
+    case GFS_TECPLOT: {
+      gfs_domain_write_tecplot (domain, output->max_depth, domain->variables_io, output->precision,
+				GFS_OUTPUT (event)->file->fp);
+      break;
+    }
+
+    default:
+      g_assert_not_reached ();
+    }
+    if (!output->var)
+      g_slist_free (domain->variables_io);
+    domain->variables_io = NULL;
+    domain->binary =       TRUE;
+    sim->output_solid   =  TRUE;
+    fflush (GFS_OUTPUT (event)->file->fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void output_simulation_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputSimulation * output = GFS_OUTPUT_SIMULATION (o);
+  GSList * i = output->var;
+
+  (* GTS_OBJECT_CLASS (gfs_output_simulation_class ())->parent_class->write) (o, fp);
+
+  fputs (" {", fp);
+  if (output->max_depth != -1)
+    fprintf (fp, " depth = %d", output->max_depth);
+  if (i != NULL) {
+    fprintf (fp, " variables = %s", GFS_VARIABLE1 (i->data)->name);
+    i = i->next;
+    while (i) {
+      fprintf (fp, ",%s", GFS_VARIABLE1 (i->data)->name);
+      i = i->next;
+    }
+  }
+  if (!output->binary)
+    fputs (" binary = 0", fp);
+  if (!output->solid)
+    fputs (" solid = 0", fp);
+  switch (output->format) {
+  case GFS_TEXT:    fputs (" format = text", fp);    break;
+  case GFS_VTK:     fputs (" format = VTK", fp);     break;
+  case GFS_TECPLOT: fputs (" format = Tecplot", fp); break;
+  default: break;
+  }
+  if (output->precision != default_precision)
+    fprintf (fp, " precision = %s", output->precision);
+  fputs (" }", fp);
+}
+
+static void output_simulation_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_output_simulation_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsOutputSimulation * output = GFS_OUTPUT_SIMULATION (*o);
+
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_INT,    "depth",     TRUE},
+      {GTS_STRING, "variables", TRUE},
+      {GTS_INT,    "binary",    TRUE},
+      {GTS_INT,    "solid",     TRUE},
+      {GTS_STRING, "format",    TRUE},
+      {GTS_STRING, "precision", TRUE},
+      {GTS_NONE}
+    };
+    gchar * variables = NULL, * format = NULL, * precision = NULL;
+
+    var[0].data = &output->max_depth;
+    var[1].data = &variables;
+    var[2].data = &output->binary;
+    var[3].data = &output->solid;
+    var[4].data = &format;
+    var[5].data = &precision;
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR) {
+      g_free (variables);
+      return;
+    }
+
+    if (variables != NULL) {
+      gchar * error = NULL;
+      GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (output));
+      GSList * vars = gfs_variables_from_list (domain->variables, variables, &error);
+
+      if (vars == NULL) {
+	gts_file_variable_error (fp, var, "variables",
+				 "unknown variable `%s'", error);
+	g_free (variables);
+	return;
+      }
+      g_slist_free (output->var);
+      output->var = vars;
+      g_free (variables);
+    }
+
+    if (format != NULL) {
+      if (!strcmp (format, "gfs"))
+	output->format = GFS;
+      else if (!strcmp (format, "text"))
+	output->format = GFS_TEXT;
+      else if (!strcmp (format, "VTK"))
+	output->format = GFS_VTK;
+      else if (!strcmp (format, "Tecplot"))
+	output->format = GFS_TECPLOT;
+      else {
+	gts_file_variable_error (fp, var, "format",
+				 "unknown format `%s'", format);
+	g_free (format);
+	return;
+      }
+      g_free (format);
+    }
+
+    if (precision != NULL) {
+      if (output->precision != default_precision)
+	g_free (output->precision);
+      output->precision = precision;
+    }
+  }
+}
+
+static void gfs_output_simulation_class_init (GfsEventClass * klass)
+{
+  klass->event = output_simulation_event;
+  GTS_OBJECT_CLASS (klass)->destroy = output_simulation_destroy;
+  GTS_OBJECT_CLASS (klass)->read = output_simulation_read;
+  GTS_OBJECT_CLASS (klass)->write = output_simulation_write;
+}
+
+static void gfs_output_simulation_init (GfsOutputSimulation * object)
+{
+  object->max_depth = -1;
+  object->var = NULL;
+  object->binary = 1;
+  object->solid = 1;
+  object->format = GFS;
+  object->precision = default_precision;
+}
+
+GfsOutputClass * gfs_output_simulation_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_simulation_info = {
+      "GfsOutputSimulation",
+      sizeof (GfsOutputSimulation),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_simulation_class_init,
+      (GtsObjectInitFunc) gfs_output_simulation_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_simulation_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputBoundaries: Object */
+
+static gboolean output_boundaries_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_output_class())->event) (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+    
+    gfs_draw_refined_boundaries (domain, fp);
+    gfs_draw_solid_boundaries (domain, fp);
+    gfs_draw_boundary_conditions (domain, fp);
+    fflush (fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_boundaries_class_init (GfsEventClass * klass)
+{
+  klass->event = output_boundaries_event;
+}
+
+GfsOutputClass * gfs_output_boundaries_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_boundaries_info = {
+      "GfsOutputBoundaries",
+      sizeof (GfsOutput),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_boundaries_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_boundaries_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalar: Object */
+
+static void gfs_output_scalar_destroy (GtsObject * o)
+{
+  GfsOutputScalar * output = GFS_OUTPUT_SCALAR (o);
+
+  if (output->box)
+    gts_object_destroy (GTS_OBJECT (output->box));
+  gts_object_destroy (GTS_OBJECT (output->f));
+  g_free (output->name);
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_output_scalar_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputScalar * output;
+
+  if (GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  output = GFS_OUTPUT_SCALAR (*o);
+  output->autoscale = TRUE;
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    else if (!strcmp (fp->token->str, "v")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (output->f, gfs_object_simulation (*o), fp);
+      output->name = gfs_function_description (output->f, TRUE);
+    }
+    else if (!strcmp (fp->token->str, "min")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      output->min = gfs_read_constant (fp, gfs_object_simulation (*o));
+      if (fp->type == GTS_ERROR)
+	return;
+      if (output->min > output->max) {
+	gts_file_error (fp, "min `%g' must be smaller than or equal to max `%g'", 
+			output->min, output->max);
+	return;
+      }
+      output->autoscale = FALSE;
+    }
+    else if (!strcmp (fp->token->str, "max")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      output->max = gfs_read_constant (fp, gfs_object_simulation (*o));
+      if (fp->type == GTS_ERROR)
+	return;
+      if (output->max < output->min) {
+	gts_file_error (fp, "max `%g' must be larger than or equal to min `%g'", 
+			output->max, output->min);
+	return;
+      }
+      output->autoscale = FALSE;
+    }
+    else if (!strcmp (fp->token->str, "maxlevel")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting an integer (maxlevel)");
+	return;
+      }
+      output->maxlevel = atoi (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "box")) {
+      gchar * box, * s;
+
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_STRING) {
+	gts_file_error (fp, "expecting a string (box)");
+	return;
+      }
+      box = g_strdup (fp->token->str);
+      s = strtok (box, ",");
+      output->box = GTS_BBOX (gts_object_new (GTS_OBJECT_CLASS (gts_bbox_class ())));
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (x1)");
+	g_free (box);
+	return;
+      }
+      output->box->x1 = atof (s);
+      s = strtok (NULL, ",");
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (y1)");
+	g_free (box);
+	return;
+      }
+      output->box->y1 = atof (s);
+      s = strtok (NULL, ",");
+#if (!FTT_2D)
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (z1)");
+	g_free (box);
+	return;
+      }
+      output->box->z1 = atof (s);
+      s = strtok (NULL, ",");
+#endif /* 3D */
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (x2)");
+	g_free (box);
+	return;
+      }
+      output->box->x2 = atof (s);
+      if (output->box->x2 < output->box->x1) {
+	gts_file_error (fp, "x2 must be larger than x1");
+	g_free (box);
+	return;
+      }
+      s = strtok (NULL, ",");
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (y2)");
+	g_free (box);
+	return;
+      }
+      output->box->y2 = atof (s);
+      if (output->box->y2 < output->box->y1) {
+	gts_file_error (fp, "y2 must be larger than y1");
+	g_free (box);
+	return;
+      }
+#if (!FTT_2D)
+      s = strtok (NULL, ",");
+      if (s == NULL) {
+	gts_file_error (fp, "expecting a number (z2)");
+	g_free (box);
+	return;
+      }
+      output->box->z2 = atof (s);
+      if (output->box->z2 < output->box->z1) {
+	gts_file_error (fp, "z2 must be larger than z1");
+	g_free (box);
+	return;
+      }
+#endif /* 3D */
+      g_free (box);
+      gts_file_next_token (fp);
+    }
+    else {
+      gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+      return;
+    }
+  }
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void gfs_output_scalar_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputScalar * output = GFS_OUTPUT_SCALAR (o);
+
+  if (GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class->write) 
+      (o, fp);
+
+  fputs (" { v = ", fp);
+  gfs_function_write (output->f, fp);
+  if (output->maxlevel >= 0)
+    fprintf (fp, " maxlevel = %d", output->maxlevel);
+  if (output->box != NULL)
+#if FTT_2D
+    fprintf (fp, " box = %g,%g,%g,%g", 
+	     output->box->x1, output->box->y1, output->box->x2, output->box->y2);
+#else  /* 3D */
+    fprintf (fp, " box = %g,%g,%g,%g,%g,%g",
+	     output->box->x1, output->box->y1, output->box->z1,
+	     output->box->x2, output->box->y2, output->box->z2);
+#endif /* 3D */
+  if (!output->autoscale)
+    fprintf (fp, " min = %g max = %g }", output->min, output->max);
+  else
+    fputs (" }", fp);
+}
+
+static void update_v (FttCell * cell, GfsOutputScalar * output)
+{
+  GFS_VALUE (cell, output->v) = gfs_function_value (output->f, cell);
+}
+
+static gboolean gfs_output_scalar_event (GfsEvent * event,
+					 GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+
+    if (!(output->v = gfs_function_get_variable (output->f)) ||
+	gfs_variable_is_dimensional (output->v)) {
+      output->v = gfs_temporary_variable (domain);
+      gfs_domain_cell_traverse (domain,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) update_v, output);
+    }
+    if (output->maxlevel >= 0)
+        gfs_domain_cell_traverse (domain,
+				  FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				  (FttCellTraverseFunc) output->v->fine_coarse,
+				  output->v);
+    if (output->autoscale) {
+      GtsRange stats = gfs_domain_stats_variable (domain, output->v, 
+	     FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, output->maxlevel);
+
+      output->min = stats.min;
+      output->max = stats.max;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_post_event (GfsEvent * event,
+					  GfsSimulation * sim)
+{
+  GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+
+  if (output->v != gfs_function_get_variable (output->f)) {
+    gts_object_destroy (GTS_OBJECT (output->v));
+    output->v = NULL;
+  }
+}
+
+static void gfs_output_scalar_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_event;
+  GFS_EVENT_CLASS (klass)->post_event = gfs_output_scalar_post_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_scalar_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_scalar_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_scalar_destroy;
+}
+
+static void gfs_output_scalar_init (GfsOutputScalar * object)
+{
+  object->f = gfs_function_new (gfs_function_class (), 0.);
+  object->min = -G_MAXDOUBLE;
+  object->max =  G_MAXDOUBLE;
+  object->autoscale = TRUE;
+  object->maxlevel = -1;
+  object->box = NULL;
+}
+
+GfsOutputClass * gfs_output_scalar_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_info = {
+      "GfsOutputScalar",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_class_init,
+      (GtsObjectInitFunc) gfs_output_scalar_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_class ()),
+				  &gfs_output_scalar_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalarNorm: Object */
+
+static gboolean gfs_output_scalar_norm_event (GfsEvent * event, 
+					      GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_norm_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GfsNorm norm = gfs_domain_norm_variable (GFS_DOMAIN (sim), 
+					     output->v, NULL,
+					     FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+					     output->maxlevel);
+
+    fprintf (GFS_OUTPUT (event)->file->fp, 
+	     "%s time: %g first: % 10.3e second: % 10.3e infty: % 10.3e\n",
+	     output->name,
+	     sim->time.t,
+	     norm.first, norm.second, norm.infty);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_norm_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_norm_event;
+}
+
+GfsOutputClass * gfs_output_scalar_norm_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_norm_info = {
+      "GfsOutputScalarNorm",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_norm_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_scalar_norm_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalarStats: Object */
+
+static gboolean gfs_output_scalar_stats_event (GfsEvent * event, 
+					     GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_stats_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GtsRange stats = gfs_domain_stats_variable (GFS_DOMAIN (sim), 
+						output->v,
+						FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+						output->maxlevel);
+
+    fprintf (GFS_OUTPUT (event)->file->fp, 
+	     "%s time: %g min: %10.3e avg: %10.3e | %10.3e max: %10.3e\n",
+	     output->name, sim->time.t,
+	     stats.min, stats.mean, stats.stddev, stats.max);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_stats_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_stats_event;
+}
+
+GfsOutputClass * gfs_output_scalar_stats_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_stats_info = {
+      "GfsOutputScalarStats",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_stats_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_scalar_stats_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalarSum: Object */
+
+static void add (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  gdouble vol = gfs_cell_volume (cell, v->domain);
+  gdouble * sum = data[1];
+
+  *sum += vol*GFS_VALUE (cell, v);
+}
+
+static gboolean gfs_output_scalar_sum_event (GfsEvent * event, 
+					     GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_sum_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    gpointer data[2];
+    gdouble sum = 0.;
+
+    data[0] = output->v;
+    data[1] = &sum;
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+			      FTT_PRE_ORDER, 
+			      FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,
+			      output->maxlevel,
+			      (FttCellTraverseFunc) add, data);
+    gfs_all_reduce (GFS_DOMAIN (sim), sum, MPI_DOUBLE, MPI_SUM);
+    fprintf (GFS_OUTPUT (event)->file->fp, 
+	     "%s time: %g sum: % 15.6e\n", output->name, sim->time.t, 
+	     sum*pow (sim->physical_params.L, FTT_DIMENSION));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_sum_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_sum_event;
+}
+
+GfsOutputClass * gfs_output_scalar_sum_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_sum_info = {
+      "GfsOutputScalarSum",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_sum_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_scalar_sum_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalarMaxima: Object */
+
+static void gfs_output_scalar_maxima_destroy (GtsObject * o)
+{
+  guint i;
+
+  for (i = 0; i < 4; i++)
+    g_free (GFS_OUTPUT_SCALAR_MAXIMA (o)->m[i]);
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_maxima_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_output_scalar_maxima_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputScalarMaxima * m;
+  guint i;
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_maxima_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (N)");
+    return;
+  }
+  m = GFS_OUTPUT_SCALAR_MAXIMA (*o);
+  m->N = atoi (fp->token->str);
+  gts_file_next_token (fp);
+
+  for (i = 0; i < 4; i++)
+    m->m[i] = g_malloc (sizeof (gdouble)*m->N);
+}
+
+static void gfs_output_scalar_maxima_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_maxima_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %d", GFS_OUTPUT_SCALAR_MAXIMA (o)->N);
+}
+
+static void maxima (FttCell * cell, GfsOutputScalarMaxima * m)
+{
+  guint i;
+
+  for (i = 0; i < m->N; i++) {
+    gdouble v = GFS_VARIABLE (cell, GFS_OUTPUT_SCALAR (m)->v->i);
+
+    if (v > m->m[3][i]) {
+      FttVector p;
+
+      gfs_cell_cm (cell, &p);
+      gfs_simulation_map_inverse (gfs_object_simulation (m), &p);
+      m->m[0][i] = p.x; m->m[1][i] = p.y; m->m[2][i] = p.z;
+      m->m[3][i] = v;
+      return;
+    }
+  }
+}
+
+static gboolean gfs_output_scalar_maxima_event (GfsEvent * event, 
+						GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_maxima_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GfsOutputScalarMaxima * m = GFS_OUTPUT_SCALAR_MAXIMA (event);
+    guint i;
+
+    for (i = 0; i < m->N; i++)
+      m->m[3][i] = -G_MAXDOUBLE;
+
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+			      FTT_PRE_ORDER, 
+			      FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,
+			      output->maxlevel,
+			      (FttCellTraverseFunc) maxima, m);
+    for (i = 0; i < m->N; i++)
+      fprintf (GFS_OUTPUT (event)->file->fp, 
+	       "%s time: %g #: %d x: %g y: %g z: %g value: %g\n", 
+	       output->name, sim->time.t, i,
+	       m->m[0][i], m->m[1][i], m->m[2][i],
+	       m->m[3][i]);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_maxima_class_init (GfsOutputClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_scalar_maxima_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_scalar_maxima_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_scalar_maxima_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_maxima_event;
+}
+
+GfsOutputClass * gfs_output_scalar_maxima_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_maxima_info = {
+      "GfsOutputScalarMaxima",
+      sizeof (GfsOutputScalarMaxima),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_maxima_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_scalar_maxima_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputScalarHistogram: Object */
+
+static void gfs_output_scalar_histogram_destroy (GtsObject * o)
+{
+  GfsOutputScalarHistogram * output = GFS_OUTPUT_SCALAR_HISTOGRAM (o);
+
+  g_free (output->x);
+  g_free (output->w);
+  if (output->wf)
+    gts_object_destroy (GTS_OBJECT (output->wf));
+  if (output->yf) {
+    gts_object_destroy (GTS_OBJECT (output->yf));
+    g_free (output->y);
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_histogram_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_output_scalar_histogram_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputScalarHistogram * output;
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_histogram_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  output = GFS_OUTPUT_SCALAR_HISTOGRAM (*o);
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    else if (!strcmp (fp->token->str, "n")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting a number (n)");
+	return;
+      }
+      output->n = atoi (fp->token->str);
+      if (output->n <= 0) {
+	gts_file_error (fp, "n `%d' must be strictly positive", output->n);
+	return;
+      }
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "w")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      output->wf = gfs_function_new (gfs_function_class (), 0.);
+      gfs_function_read (output->wf, gfs_object_simulation (*o), fp);
+    }
+    else if (!strcmp (fp->token->str, "y")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting '='");
+	return;
+      }
+      gts_file_next_token (fp);
+      output->yf = gfs_function_new (gfs_function_class (), 0.);
+      gfs_function_read (output->yf, gfs_object_simulation (*o), fp);
+    }
+    else {
+      gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+      return;
+    }
+  }
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+
+  output->x = g_malloc0 (output->n*sizeof (gdouble));
+  output->w = g_malloc0 (output->n*sizeof (gdouble));
+  if (output->yf)
+    output->y = g_malloc0 (output->n*sizeof (gdouble));
+}
+
+static void gfs_output_scalar_histogram_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputScalarHistogram * output = GFS_OUTPUT_SCALAR_HISTOGRAM (o);
+
+  (* GTS_OBJECT_CLASS (gfs_output_scalar_histogram_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " { n = %d", output->n);
+  if (output->wf) {
+    fputs (" w = ", fp);
+    gfs_function_write (output->wf, fp);
+  }
+  if (output->yf) {
+    fputs (" y = ", fp);
+    gfs_function_write (output->yf, fp);
+  }
+  fputs (" }", fp);
+}
+
+static void update_histogram (FttCell * cell, GfsOutputScalar * h)
+{
+  GfsOutputScalarHistogram * hi = GFS_OUTPUT_SCALAR_HISTOGRAM (h);
+  gdouble v = GFS_VALUE (cell, h->v);
+  gint i = (v - h->min)/(h->max - h->min)*hi->n;
+
+  if (i >= 0 && i < hi->n) {
+    gdouble w = hi->dt;
+
+    if (hi->wf)
+      w *= gfs_function_value (hi->wf, cell);
+    else
+      w *= gfs_cell_volume (cell, h->v->domain);
+
+    hi->W += w;
+    hi->w[i] += w;
+    hi->x[i] += v*w;
+    if (hi->yf)
+      hi->y[i] += w*gfs_function_value (hi->yf, cell);
+  }
+}
+
+static gboolean gfs_output_scalar_histogram_event (GfsEvent * event,
+						   GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_scalar_histogram_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalarHistogram * h = GFS_OUTPUT_SCALAR_HISTOGRAM (event);
+
+    if (gfs_event_is_repetitive (event))
+      h->dt = h->last >= 0. ? sim->time.t - h->last : 0.;
+    else
+      h->dt = 1.;
+
+    if (h->dt > 0.) {
+      GfsOutput * output = GFS_OUTPUT (event);
+      guint i;
+
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, 
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+				GFS_OUTPUT_SCALAR (output)->maxlevel,
+				(FttCellTraverseFunc) update_histogram, output);
+
+      if (output->file && !output->dynamic)
+	output->file->fp = freopen (output->format, "w", output->file->fp);
+      for (i = 0; i < h->n; i++)
+	if (h->w[i] > 0.) {
+	  fprintf (output->file->fp, "%g %g", h->x[i]/h->w[i], h->w[i]/h->W);
+	  if (h->yf)
+	    fprintf (output->file->fp, " %g", h->y[i]/h->w[i]);
+	  fputc ('\n', output->file->fp);
+	}
+      if (output->file && !output->dynamic)
+	fflush (output->file->fp);
+    }
+    h->last = sim->time.t;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_scalar_histogram_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_scalar_histogram_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_scalar_histogram_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_scalar_histogram_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_scalar_histogram_destroy;
+}
+
+static void gfs_output_scalar_histogram_init (GfsOutputScalarHistogram * object)
+{
+  GFS_OUTPUT_SCALAR (object)->min = -1.;
+  GFS_OUTPUT_SCALAR (object)->max =  1.;
+  GFS_OUTPUT_SCALAR (object)->autoscale = FALSE;
+  object->n = 100;
+  object->W = 0.;
+  object->last = -1.;
+}
+
+GfsOutputClass * gfs_output_scalar_histogram_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_scalar_histogram_info = {
+      "GfsOutputScalarHistogram",
+      sizeof (GfsOutputScalarHistogram),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_scalar_histogram_class_init,
+      (GtsObjectInitFunc) gfs_output_scalar_histogram_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_scalar_histogram_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputDropletSums: Object */
+
+static void gfs_output_droplet_sums_destroy (GtsObject * object)
+{
+  GfsOutputDropletSums * d = GFS_OUTPUT_DROPLET_SUMS (object);
+  gts_object_destroy (GTS_OBJECT (d->c));
+  if (d->tag)
+    gts_object_destroy (GTS_OBJECT (d->tag));
+
+  (* GTS_OBJECT_CLASS (gfs_output_droplet_sums_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_output_droplet_sums_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_output_droplet_sums_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsOutputDropletSums * d = GFS_OUTPUT_DROPLET_SUMS (*o);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  gfs_function_read (d->c, domain, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type == GTS_STRING) {
+    if (!(d->tag = gfs_domain_get_or_add_variable (domain, fp->token->str, "Droplet index"))) {
+      gts_file_error (fp, "`%s' is a reserved variable name", fp->token->str);
+      return;
+    }
+    gts_file_next_token (fp);
+  }
+}
+
+static void gfs_output_droplet_sums_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputDropletSums * d = GFS_OUTPUT_DROPLET_SUMS (o);
+
+  (* GTS_OBJECT_CLASS (gfs_output_droplet_sums_class ())->parent_class->write) (o, fp);
+
+  gfs_function_write (d->c, fp);
+  if (d->tag)
+    fprintf (fp, " %s", d->tag->name);
+}
+
+typedef struct {
+  double v, f;
+} VolumePair;
+
+typedef struct {
+  GfsVariable * s, * c, * tag;
+  VolumePair * v;
+  guint n;
+  GfsFunction * fc;
+} DropSumsPar;
+
+static void droplet_sums (FttCell * cell, DropSumsPar * p)
+{
+  guint i = GFS_VALUE (cell, p->tag);
+  if (i > 0) {
+    p->v[i - 1].v += GFS_VALUE (cell, p->c)*ftt_cell_volume (cell);
+    p->v[i - 1].f += GFS_VALUE (cell, p->s);
+  }
+}
+
+static void compute_c (FttCell * cell, DropSumsPar * p)
+{
+  GFS_VALUE (cell, p->c) = gfs_function_value (p->fc, cell);
+}
+
+static int volume_sort (const void * p1, const void * p2)
+{
+  VolumePair * a = (VolumePair *) p1;
+  VolumePair * b = (VolumePair *) p2;
+  return a->v < b->v ? 1 : -1;
+}
+
+static gboolean gfs_output_droplet_sums_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_droplet_sums_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputDropletSums * d = GFS_OUTPUT_DROPLET_SUMS (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    DropSumsPar p;
+    p.s = GFS_OUTPUT_SCALAR (event)->v;
+    p.c = gfs_function_get_variable (d->c);
+    if (!p.c) {
+      p.c = gfs_temporary_variable (domain);
+      p.fc = d->c;
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+				(FttCellTraverseFunc) compute_c, &p);
+    }
+    p.tag = d->tag ? d->tag : gfs_temporary_variable (domain);
+    p.n = gfs_domain_tag_droplets (domain, p.c, p.tag);
+    if (p.n > 0) {
+      p.v = g_malloc0 (p.n*sizeof (VolumePair));
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) droplet_sums, &p);
+#ifdef HAVE_MPI
+      if (domain->pid >= 0) {
+	VolumePair * gv = g_malloc0 (p.n*sizeof (VolumePair));
+	MPI_Allreduce (p.v, gv, p.n*2, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
+	g_free (p.v);
+	p.v = gv;
+      }
+#endif /* HAVE_MPI */      
+      qsort (p.v, p.n, sizeof (VolumePair), volume_sort);
+      guint i;
+      for (i = 0; i < p.n; i++)
+	fprintf (GFS_OUTPUT (event)->file->fp, "%g %d %.12g\n", sim->time.t, i + 1, p.v[i].f);
+      g_free (p.v);
+    }
+    if (p.tag != d->tag)
+      gts_object_destroy (GTS_OBJECT (p.tag));
+    if (!gfs_function_get_variable (d->c))
+      gts_object_destroy (GTS_OBJECT (p.c));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_droplet_sums_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_droplet_sums_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_droplet_sums_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_droplet_sums_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_output_droplet_sums_destroy;
+}
+
+static void gfs_output_droplet_sums_init (GfsOutputDropletSums * d)
+{
+  d->c = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsOutputClass * gfs_output_droplet_sums_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_droplet_sums_info = {
+      "GfsOutputDropletSums",
+      sizeof (GfsOutputDropletSums),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_droplet_sums_class_init,
+      (GtsObjectInitFunc) gfs_output_droplet_sums_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_droplet_sums_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputErrorNorm: Object */
+
+static void output_error_norm_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_OUTPUT_ERROR_NORM (o)->s));
+  gts_object_destroy (GTS_OBJECT (GFS_OUTPUT_ERROR_NORM (o)->w));
+
+  (* GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class->destroy) (o);
+}
+
+static void output_error_norm_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputErrorNorm * n;
+
+  if (GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  n = GFS_OUTPUT_ERROR_NORM (*o);
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a parameter");
+      return;
+    }
+    else if (!strcmp (fp->token->str, "unbiased")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting an integer");
+	return;
+      }
+      n->unbiased = atoi (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "relative")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_INT) {
+	gts_file_error (fp, "expecting an integer");
+	return;
+      }
+      n->relative = atoi (fp->token->str);
+      gts_file_next_token (fp);
+    }
+    else if (!strcmp (fp->token->str, "s")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (n->s, gfs_object_simulation (*o), fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+    else if (!strcmp (fp->token->str, "w")) {
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+      gfs_function_read (n->w, gfs_object_simulation (*o), fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+    else if (!strcmp (fp->token->str, "v")) {
+      GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+      if (fp->type != GTS_STRING) {
+	gts_file_error (fp, "expecting a variable name");
+	return;
+      }
+      if (!(n->v = gfs_domain_get_or_add_variable (domain, fp->token->str, "Error field"))) {
+	gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+	return;
+      }
+      gts_file_next_token (fp);
+    }
+    else {
+      gts_file_error (fp, "unknown identifier `%s'", fp->token->str);
+      return;
+    }
+  }
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void output_error_norm_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputErrorNorm * n = GFS_OUTPUT_ERROR_NORM (o);
+
+  if (GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class->write) 
+      (o, fp);
+  fputs (" { s = ", fp);
+  gfs_function_write (n->s, fp);
+  fputs (" w = ", fp);
+  gfs_function_write (n->w, fp);
+  fprintf (fp, " unbiased = %d relative = %d", n->unbiased, n->relative);
+  if (n->v)
+    fprintf (fp, " v = %s }", n->v->name);
+  else
+    fputs (" }", fp);
+}
+
+static void reference_solution (FttCell * cell, GfsOutputScalar * o)
+{
+  GFS_VALUE (cell, GFS_OUTPUT_ERROR_NORM (o)->v) = 
+    gfs_function_value (GFS_OUTPUT_ERROR_NORM (o)->s, cell);
+}
+
+static void substract (FttCell * cell, GfsOutputScalar * o)
+{
+  GFS_VALUE (cell, GFS_OUTPUT_ERROR_NORM (o)->v) = GFS_VALUE (cell, o->v) -
+    GFS_VALUE (cell, GFS_OUTPUT_ERROR_NORM (o)->v);
+}
+
+static void compute_error (FttCell * cell, GfsOutputScalar * o)
+{
+  GFS_VALUE (cell, GFS_OUTPUT_ERROR_NORM (o)->v) = GFS_VALUE (cell, o->v) -
+    gfs_function_value (GFS_OUTPUT_ERROR_NORM (o)->s, cell);
+}
+
+static void remove_bias (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsNorm * norm = data[1];
+  GFS_VALUE (cell, v) -= norm->bias;
+}
+
+static gboolean gfs_output_error_norm_event (GfsEvent * event, 
+					     GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GfsOutputErrorNorm * enorm = GFS_OUTPUT_ERROR_NORM (event);
+    GfsVariable * v = enorm->v;
+    GfsNorm norm, snorm;
+
+    if (v == NULL)
+      enorm->v = gfs_temporary_variable (domain);
+    if (enorm->relative) {
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,  
+				output->maxlevel,
+				(FttCellTraverseFunc) reference_solution, output);
+      snorm = gfs_domain_norm_variable (domain, enorm->v, enorm->w,
+					FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+					output->maxlevel);
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,  
+				output->maxlevel,
+				(FttCellTraverseFunc) substract, output);
+    }
+    else
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,  
+				output->maxlevel,
+				(FttCellTraverseFunc) compute_error, output);
+    norm = gfs_domain_norm_variable (domain, enorm->v, enorm->w,
+				     FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+				     output->maxlevel);
+    if (GFS_OUTPUT_ERROR_NORM (event)->unbiased) {
+      gpointer data[2];
+
+      data[0] = enorm->v;
+      data[1] = &norm;
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,  
+				output->maxlevel,
+				(FttCellTraverseFunc) remove_bias, data);
+      norm = gfs_domain_norm_variable (domain, enorm->v, enorm->w,
+				       FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+				       output->maxlevel);
+    }
+    if (v == NULL) {
+      gts_object_destroy (GTS_OBJECT (enorm->v));
+      enorm->v = NULL;
+    }
+    if (enorm->relative) {
+      if (snorm.first > 0.)  norm.first  /= snorm.first;
+      if (snorm.second > 0.) norm.second /= snorm.second;
+      if (snorm.infty > 0.)  norm.infty  /= snorm.infty;
+    }
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "%s time: %g first: % 10.3e second: % 10.3e infty: % 10.3e bias: %10.3e\n",
+	     output->name, sim->time.t,
+	     norm.first, norm.second, norm.infty, norm.bias);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_error_norm_class_init (GfsOutputClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = output_error_norm_destroy;
+  GTS_OBJECT_CLASS (klass)->read = output_error_norm_read;
+  GTS_OBJECT_CLASS (klass)->write = output_error_norm_write;
+  GFS_EVENT_CLASS (klass)->event = gfs_output_error_norm_event;
+}
+
+static void output_error_norm_init (GfsOutputErrorNorm * e)
+{
+  e->s = gfs_function_new (gfs_function_class (), 0.);
+  e->w = gfs_function_new (gfs_function_class (), 1.);
+}
+
+GfsOutputClass * gfs_output_error_norm_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_error_norm_info = {
+      "GfsOutputErrorNorm",
+      sizeof (GfsOutputErrorNorm),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_error_norm_class_init,
+      (GtsObjectInitFunc) output_error_norm_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_error_norm_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputCorrelation: Object */
+
+static void compute_correlation (FttCell * cell, gpointer * data)
+{
+  GfsOutputScalar * o = data[0];
+  gdouble * bias = data[1];
+  gdouble * sum = data[2];
+  gdouble * sumref = data[3];
+  gdouble v, ref, w;
+
+  ref = gfs_function_value (GFS_OUTPUT_ERROR_NORM (o)->s, cell);
+  v = GFS_VALUE (cell, o->v) - *bias;
+  w = gfs_cell_volume (cell, o->v->domain);
+  *sumref += ref*ref*w;
+  *sum += v*ref*w;
+}
+
+static gboolean gfs_output_correlation_event (GfsEvent * event, 
+					      GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_error_norm_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    GfsOutputErrorNorm * enorm = GFS_OUTPUT_ERROR_NORM (event);
+    GfsVariable * v = enorm->v;
+    gdouble bias = 0., sum = 0., sumref = 0.;
+    gpointer data[4];
+
+    if (GFS_DOMAIN (sim)->pid != -1)
+      g_assert_not_implemented ();
+
+    if (v == NULL)
+      enorm->v = gfs_temporary_variable (GFS_DOMAIN (sim));
+    if (enorm->unbiased) {
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER,
+				FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,
+				output->maxlevel,
+				(FttCellTraverseFunc) compute_error, output);
+      bias = gfs_domain_norm_variable (GFS_DOMAIN (sim), enorm->v, NULL,
+				       FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, 
+				       output->maxlevel).bias;
+    }
+    data[0] = output;
+    data[1] = &bias;
+    data[2] = &sum;
+    data[3] = &sumref;
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER,
+			      FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,
+			      output->maxlevel,
+			      (FttCellTraverseFunc) compute_correlation, data);
+    if (v == NULL) {
+      gts_object_destroy (GTS_OBJECT (enorm->v));
+      enorm->v = NULL;
+    }
+    fprintf (GFS_OUTPUT (event)->file->fp,
+	     "%s time: %g %10.3e\n",
+	     output->name, sim->time.t, sumref > 0. ? sum/sumref : 0.);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_correlation_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_correlation_event;
+}
+
+GfsOutputClass * gfs_output_correlation_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_correlation_info = {
+      "GfsOutputCorrelation",
+      sizeof (GfsOutputErrorNorm),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_correlation_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_error_norm_class ()),
+				  &gfs_output_correlation_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputSquares: Object */
+
+static gboolean gfs_output_squares_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_squares_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+    
+    gfs_write_squares (GFS_DOMAIN (sim), 
+		       output->v, output->min, output->max,
+		       FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL,
+		       output->maxlevel, NULL, 
+		       GFS_OUTPUT (event)->file->fp);
+    fflush (GFS_OUTPUT (event)->file->fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_squares_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_squares_event;
+}
+
+GfsOutputClass * gfs_output_squares_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_squares_info = {
+      "GfsOutputSquares",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_squares_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_squares_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputStreamline: Object */
+
+static void gfs_output_streamline_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsOutputStreamline * l = GFS_OUTPUT_STREAMLINE (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.x)");
+    return;
+  }
+  l->p.x = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.y)");
+    return;
+  }
+  l->p.y = atof (fp->token->str);
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT) {
+    gts_file_error (fp, "expecting a number (p.z)");
+    return;
+  }
+  l->p.z = atof (fp->token->str);
+  gts_file_next_token (fp);
+}
+
+static void gfs_output_streamline_write (GtsObject * o, FILE * fp)
+{
+  GfsOutputStreamline * l = GFS_OUTPUT_STREAMLINE (o);
+
+  if (GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class->write) 
+      (o, fp);
+  fprintf (fp, " %g %g %g", l->p.x, l->p.y, l->p.z);
+}
+
+static gboolean gfs_output_streamline_event (GfsEvent * event, 
+					    GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_streamline_class ())->parent_class)->event)
+      (event,sim)) {
+    FttVector p = GFS_OUTPUT_STREAMLINE (event)->p;
+    gfs_simulation_map (sim, &p);
+    GList * stream = gfs_streamline_new (GFS_DOMAIN (sim),
+					 gfs_domain_velocity (GFS_DOMAIN (sim)),
+					 p,
+					 GFS_OUTPUT_SCALAR (event)->v,
+					 0., 0.,
+					 TRUE,
+					 NULL, NULL);
+    /* fixme: mapping is not taken into account */
+    gfs_streamline_write (stream, GFS_OUTPUT (event)->file->fp);
+    fflush (GFS_OUTPUT (event)->file->fp);
+    gfs_streamline_destroy (stream);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_streamline_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_streamline_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_streamline_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_output_streamline_write;
+}
+
+GfsOutputClass * gfs_output_streamline_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_streamline_info = {
+      "GfsOutputStreamline",
+      sizeof (GfsOutputStreamline),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_streamline_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_streamline_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputParticle: Object */
+
+static gboolean gfs_output_particle_event (GfsEvent * event, 
+					   GfsSimulation * sim)
+{
+  GfsOutputLocation * location = GFS_OUTPUT_LOCATION (event);
+  gboolean ret = FALSE;
+  guint i;
+
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_location_class ())->parent_class)->event)
+      (event,sim)) {
+    FILE * fp = GFS_OUTPUT (event)->file->fp;
+
+    for (i = 0; i < location->p->len; i++) {
+      FttVector p = g_array_index (location->p, FttVector, i);
+      fprintf (fp, "%d %g %g %g %g\n", i, sim->time.t, p.x, p.y, p.z);
+    }
+    fflush (fp);
+    ret = TRUE;
+  }
+  
+  for (i = 0; i < location->p->len; i++) {
+    FttVector p = g_array_index (location->p, FttVector, i);
+    gfs_simulation_map (sim, &p);
+    gfs_domain_advect_point (GFS_DOMAIN (sim), &p, sim->advection_params.dt);
+    gfs_simulation_map_inverse (sim, &p);
+    g_array_index (location->p, FttVector, i) = p;
+  }
+
+  return ret;
+}
+
+static void gfs_output_particle_class_init (GfsOutputClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_output_particle_event;
+}
+
+GfsOutputClass * gfs_output_particle_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_particle_info = {
+      "GfsOutputParticle",
+      sizeof (GfsOutputLocation),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_particle_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_location_class ()),
+				  &gfs_output_particle_info);
+  }
+
+  return klass;
+}
+
+/* GfsOutputPPM: Object */
+
+static void gfs_output_ppm_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_output_ppm_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_output_ppm_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+#if (!FTT_2D)
+  if (!GFS_IS_OCEAN (gfs_object_simulation (*o))) {
+    gts_file_error (fp, 
+		    "In more than two dimensions PPM output is possible\n"
+		    "only for GfsOcean simulations");
+    return;
+  }
+#endif /* 2D3 or 3D */
+}
+
+static gboolean gfs_output_ppm_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_output_ppm_class ())->parent_class)->event) 
+      (event, sim)) {
+    GfsOutputScalar * output = GFS_OUTPUT_SCALAR (event);
+#if FTT_2D
+    GfsDomain * domain = GFS_DOMAIN (sim);
+#else /* 2D3 or 3D */
+    GfsDomain * domain = GFS_IS_OCEAN (sim) ? GFS_OCEAN (sim)->toplayer : GFS_DOMAIN (sim);
+#endif /* 2D3 or 3D */
+
+    gfs_write_ppm (domain,
+		   output->box,
+		   output->v, output->min, output->max,
+		   FTT_TRAVERSE_LEAFS|FTT_TRAVERSE_LEVEL, output->maxlevel,
+		   GFS_OUTPUT (event)->file->fp);
+    fflush (GFS_OUTPUT (event)->file->fp);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_output_ppm_class_init (GfsOutputClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_output_ppm_read;
+  GFS_EVENT_CLASS (klass)->event = gfs_output_ppm_event;
+}
+
+GfsOutputClass * gfs_output_ppm_class (void)
+{
+  static GfsOutputClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_output_ppm_info = {
+      "GfsOutputPPM",
+      sizeof (GfsOutputScalar),
+      sizeof (GfsOutputClass),
+      (GtsObjectClassInitFunc) gfs_output_ppm_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_output_scalar_class ()),
+				  &gfs_output_ppm_info);
+  }
+
+  return klass;
+}
diff --git a/src/output.h b/src/output.h
new file mode 100644
index 0000000..c35c7a9
--- /dev/null
+++ b/src/output.h
@@ -0,0 +1,367 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __OUTPUT_H__
+#define __OUTPUT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "event.h"
+
+/* GfsOutput: Header */
+
+typedef struct _GfsOutput         GfsOutput;
+typedef struct _GfsOutputClass    GfsOutputClass;
+typedef struct _GfsOutputFile     GfsOutputFile;
+
+struct _GfsOutput {
+  GfsEvent parent;
+
+  GfsOutputFile * file;
+  gchar * format;
+  GSList * formats;
+  gboolean dynamic, parallel, first_call;
+};
+
+struct _GfsOutputClass {
+  GfsEventClass parent_class;
+};
+
+#define GFS_OUTPUT(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsOutput,\
+					           gfs_output_class ())
+#define GFS_OUTPUT_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsOutputClass,\
+						   gfs_output_class())
+#define GFS_IS_OUTPUT(obj)         (gts_object_is_from_class (obj,\
+						   gfs_output_class ()))
+     
+GfsOutputClass * gfs_output_class  (void);
+void             gfs_output_mute   (GfsOutput * output);
+
+struct _GfsOutputFile {
+  guint refcount;
+  gchar * name;
+  FILE * fp;
+  gboolean is_pipe;
+};
+
+GfsOutputFile * gfs_output_file_new     (FILE * fp);
+GfsOutputFile * gfs_output_file_open    (const gchar * name,
+					 const gchar * mode);
+void            gfs_output_file_close   (GfsOutputFile * file);
+
+/* GfsOutputTime: Header */
+
+typedef struct _GfsOutputTime         GfsOutputTime;
+
+struct _GfsOutputTime {
+  /*< private >*/
+  GfsOutput parent;
+
+  /*< public >*/
+  GfsClock * clock;
+  GTimer * timer;
+};
+
+#define GFS_OUTPUT_TIME(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputTime,\
+					         gfs_output_time_class ())
+#define GFS_IS_OUTPUT_TIME(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_time_class ()))
+
+GfsOutputClass * gfs_output_time_class  (void);
+
+/* GfsOutputProgress: Header */
+
+GfsOutputClass * gfs_output_progress_class  (void);
+
+/* GfsOutputProjectionStats: Header */
+
+GfsOutputClass * gfs_output_projection_stats_class  (void);
+
+/* GfsOutputDiffusionStats: Header */
+
+GfsOutputClass * gfs_output_diffusion_stats_class  (void);
+
+/* GfsOutputSolidStats: Header */
+
+GfsOutputClass * gfs_output_solid_stats_class  (void);
+
+/* GfsOutputAdaptStats: Header */
+
+GfsOutputClass * gfs_output_adapt_stats_class  (void);
+
+/* GfsOutputTiming: Header */
+
+GfsOutputClass * gfs_output_timing_class (void);
+
+/* GfsOutputBalance: Header */
+
+GfsOutputClass * gfs_output_balance_class  (void);
+
+/* GfsOutputSolidForce: Header */
+
+typedef struct _GfsOutputSolidForce         GfsOutputSolidForce;
+
+struct _GfsOutputSolidForce {
+  /*< private >*/
+  GfsOutput parent;
+
+  /*< public >*/
+  GfsFunction * weight;
+};
+
+#define GFS_OUTPUT_SOLID_FORCE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputSolidForce,\
+					         gfs_output_solid_force_class ())
+
+GfsOutputClass * gfs_output_solid_force_class (void);
+
+/* GfsOutputLocation: Header */
+
+typedef struct _GfsOutputLocation         GfsOutputLocation;
+
+struct _GfsOutputLocation {
+  /*< private >*/
+  GfsOutput parent;
+
+  /*< public >*/
+  GArray * p;
+};
+
+#define GFS_OUTPUT_LOCATION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputLocation,\
+					         gfs_output_location_class ())
+#define GFS_IS_OUTPUT_LOCATION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_location_class ()))
+
+GfsOutputClass * gfs_output_location_class  (void);
+
+/* GfsOutputSimulation: Header */
+
+typedef struct _GfsOutputSimulation         GfsOutputSimulation;
+typedef enum   { GFS, 
+		 GFS_TEXT, 
+		 GFS_VTK, 
+		 GFS_TECPLOT }              GfsOutputSimulationFormat;
+
+struct _GfsOutputSimulation {
+  GfsOutput parent;
+
+  gint max_depth;
+  GSList * var;
+  gboolean binary, solid;
+  gchar * precision;
+  GfsOutputSimulationFormat format;
+};
+
+#define GFS_OUTPUT_SIMULATION(obj)            GTS_OBJECT_CAST (obj,\
+					     GfsOutputSimulation,\
+					     gfs_output_simulation_class ())
+#define GFS_OUTPUT_SIMULATION_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+					     GfsOutputClass,\
+					     gfs_output_simulation_class())
+#define GFS_IS_OUTPUT_SIMULATION(obj)         (gts_object_is_from_class (obj,\
+					     gfs_output_simulation_class ()))
+     
+GfsOutputClass * gfs_output_simulation_class  (void);
+
+/* GfsOutputBoundaries: Header */
+
+GfsOutputClass * gfs_output_boundaries_class  (void);
+
+/* GfsOutputScalar: Header */
+
+typedef struct _GfsOutputScalar         GfsOutputScalar;
+
+struct _GfsOutputScalar {
+  /*< private >*/
+  GfsOutput parent;
+  gboolean autoscale;
+  GfsFunction * f;
+  
+  /*< public >*/
+  GfsVariable * v;
+  gchar * name;
+  gdouble min, max;
+  gint maxlevel;
+  GtsBBox * box;
+};
+
+#define GFS_OUTPUT_SCALAR(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputScalar,\
+					         gfs_output_scalar_class ())
+#define GFS_IS_OUTPUT_SCALAR(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_scalar_class ()))
+
+GfsOutputClass * gfs_output_scalar_class  (void);
+
+/* GfsOutputScalarNorm: Header */
+
+GfsOutputClass * gfs_output_scalar_norm_class  (void);
+
+/* GfsOutputScalarStats: Header */
+
+GfsOutputClass * gfs_output_scalar_stats_class  (void);
+
+/* GfsOutputScalarSum: Header */
+
+GfsOutputClass * gfs_output_scalar_sum_class  (void);
+
+/* GfsOutputScalarMaxima: Header */
+
+typedef struct _GfsOutputScalarMaxima         GfsOutputScalarMaxima;
+
+struct _GfsOutputScalarMaxima {
+  /*< private >*/
+  GfsOutputScalar parent;
+  
+  /*< public >*/
+  guint N;
+  gdouble * m[4];
+};
+
+#define GFS_OUTPUT_SCALAR_MAXIMA(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputScalarMaxima,\
+					         gfs_output_scalar_maxima_class ())
+#define GFS_IS_OUTPUT_SCALAR_MAXIMA(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_scalar_maxima_class ()))
+
+GfsOutputClass * gfs_output_scalar_maxima_class  (void);
+
+/* GfsOutputScalarHistogram: Header */
+
+typedef struct _GfsOutputScalarHistogram         GfsOutputScalarHistogram;
+
+struct _GfsOutputScalarHistogram {
+  /*< private >*/
+  GfsOutputScalar parent;
+  
+  /*< public >*/
+  gdouble * x, * y, * w, W;
+  GfsFunction * wf, * yf;
+  gdouble last, dt;
+  guint n;
+};
+
+#define GFS_OUTPUT_SCALAR_HISTOGRAM(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputScalarHistogram,\
+					         gfs_output_scalar_histogram_class ())
+#define GFS_IS_OUTPUT_SCALAR_HISTOGRAM(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_scalar_histogram_class ()))
+
+GfsOutputClass * gfs_output_scalar_histogram_class  (void);
+
+/* GfsOutputDropletSums: Header */
+
+typedef struct _GfsOutputDropletSums         GfsOutputDropletSums;
+
+struct _GfsOutputDropletSums {
+  /*< private >*/
+  GfsOutputScalar parent;
+
+  /*< public >*/
+  GfsFunction * c;
+  GfsVariable * tag;
+};
+
+#define GFS_OUTPUT_DROPLET_SUMS(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputDropletSums,\
+					         gfs_output_droplet_sums_class ())
+#define GFS_IS_OUTPUT_DROPLET_SUMS(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_droplet_sums_class ()))
+
+GfsOutputClass * gfs_output_droplet_sums_class  (void);
+
+/* GfsOutputErrorNorm: Header */
+
+typedef struct _GfsOutputErrorNorm        GfsOutputErrorNorm;
+
+struct _GfsOutputErrorNorm {
+  /*< private >*/
+  GfsOutputScalar parent;
+  GfsVariable * v;
+  
+  /*< public >*/
+  GfsFunction * s;
+  gboolean unbiased, relative;
+  GfsFunction * w;
+};
+
+#define GFS_OUTPUT_ERROR_NORM(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsOutputErrorNorm,\
+					         gfs_output_error_norm_class ())
+#define GFS_IS_OUTPUT_ERROR_NORM(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_error_norm_class ()))
+
+GfsOutputClass * gfs_output_error_norm_class  (void);
+
+/* GfsOutputCorrelation: Header */
+
+GfsOutputClass * gfs_output_correlation_class  (void);
+
+/* GfsOutputSquares: Header */
+
+#define GFS_IS_OUTPUT_SQUARES(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_squares_class ()))
+
+GfsOutputClass * gfs_output_squares_class  (void);
+
+/* GfsOutputStreamline: Header */
+
+typedef struct _GfsOutputStreamline         GfsOutputStreamline;
+
+struct _GfsOutputStreamline {
+  /*< private >*/
+  GfsOutputScalar parent;
+
+  /*< public >*/
+  FttVector p;
+};
+
+#define GFS_OUTPUT_STREAMLINE(obj)         GTS_OBJECT_CAST (obj,\
+					       GfsOutputStreamline,\
+					       gfs_output_streamline_class ())
+#define GFS_IS_OUTPUT_STREAMLINE(obj)     (gts_object_is_from_class (obj,\
+					       gfs_output_streamline_class ()))
+
+GfsOutputClass * gfs_output_streamline_class  (void);
+
+/* GfsOutputParticle: Header */
+
+#define GFS_IS_OUTPUT_PARTICLE(obj)     (gts_object_is_from_class (obj,\
+								   gfs_output_particle_class ()))
+
+GfsOutputClass * gfs_output_particle_class  (void);
+
+/* GfsOutputPPM: Header */
+
+#define GFS_IS_OUTPUT_PPM(obj)         (gts_object_is_from_class (obj,\
+						 gfs_output_ppm_class ()))
+
+GfsOutputClass * gfs_output_ppm_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __OUTPUT_H__ */
diff --git a/src/poisson.c b/src/poisson.c
new file mode 100644
index 0000000..8dc8d21
--- /dev/null
+++ b/src/poisson.c
@@ -0,0 +1,1157 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include "poisson.h"
+#include "solid.h"
+#include "source.h"
+#include "tension.h"
+
+/**
+ * gfs_multilevel_params_write:
+ * @par: the multilevel parameters.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a text representation of the multilevel parameters
+ * @par.  
+ */
+void gfs_multilevel_params_write (GfsMultilevelParams * par, FILE * fp)
+{
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp,
+           "{\n"
+	   "  tolerance = %g\n"
+	   "  nrelax    = %u\n"
+           "  erelax    = %u\n"
+	   "  minlevel  = %u\n"
+	   "  nitermax  = %u\n"
+	   "  nitermin  = %u\n"
+	   "  weighted  = %d\n"
+	   "  beta      = %g\n",
+	   par->tolerance,
+	   par->nrelax,
+	   par->erelax,
+	   par->minlevel,
+	   par->nitermax,
+	   par->nitermin,
+	   par->weighted,
+	   par->beta);
+  if (par->omega != 1.)
+    fprintf (fp, "  omega     = %g\n", par->omega);
+  fputc ('}', fp);
+}
+
+void gfs_multilevel_params_init (GfsMultilevelParams * par)
+{
+  g_return_if_fail (par != NULL);
+
+  par->tolerance = 1e-3;
+  par->nrelax    = 4;
+  par->erelax    = 1;
+  par->minlevel  = 0;
+  par->nitermax  = 100;
+  par->nitermin  = 1;
+
+  par->dimension = FTT_DIMENSION;
+  par->weighted = FALSE;
+  par->beta = 0.5;
+  par->omega = 1.;
+}
+
+void gfs_multilevel_params_read (GfsMultilevelParams * par, GtsFile * fp)
+{
+  GtsFileVariable var[] = {
+    {GTS_DOUBLE, "tolerance", TRUE},
+    {GTS_UINT,   "nrelax",    TRUE},
+    {GTS_UINT,   "erelax",    TRUE},
+    {GTS_UINT,   "minlevel",  TRUE},
+    {GTS_UINT,   "nitermax",  TRUE},
+    {GTS_UINT,   "nitermin",  TRUE},
+    {GTS_INT,    "weighted",  TRUE},
+    {GTS_DOUBLE, "beta",      TRUE},
+    {GTS_DOUBLE, "omega",     TRUE},
+    {GTS_NONE}
+  };
+
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (fp != NULL);
+
+  var[0].data = &par->tolerance;
+  var[1].data = &par->nrelax;
+  var[2].data = &par->erelax;
+  var[3].data = &par->minlevel;
+  var[4].data = &par->nitermax;
+  var[5].data = &par->nitermin;
+  var[6].data = &par->weighted;
+  var[7].data = &par->beta;
+  var[8].data = &par->omega;
+
+  gts_file_assign_variables (fp, var);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (par->tolerance <= 0.) {
+    gts_file_variable_error (fp, var, "tolerance",
+			     "tolerance `%g' must be strictly positive",
+			     par->tolerance);
+    return;
+  }
+  if (par->nrelax == 0)
+    gts_file_variable_error (fp, var, "nrelax", "nrelax must be non zero");
+  if (par->erelax == 0)
+    gts_file_variable_error (fp, var, "erelax", "erelax must be non zero");
+  if (par->beta < 0.5 || par->beta > 1.)
+    gts_file_variable_error (fp, var, "beta", "beta must be in [0.5,1]");
+}
+
+static gdouble rate (gdouble a, gdouble b, guint n)
+{
+  if (a > 0. && b > 0. && n > 0)
+    return exp (log (b/a)/n);
+  return 0.;
+}
+
+/**
+ * gfs_multilevel_params_stats_write:
+ * @par: the multilevel parameters.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp the statistics contained in @p.
+ */
+void gfs_multilevel_params_stats_write (GfsMultilevelParams * par,
+					FILE * fp)
+{
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp,
+	   "    niter: %4d\n"
+	   "    residual.bias:   % 10.3e % 10.3e\n"
+	   "    residual.first:  % 10.3e % 10.3e %6.2g\n"
+	   "    residual.second: % 10.3e % 10.3e %6.2g\n"
+	   "    residual.infty:  % 10.3e % 10.3e %6.2g\n",
+	   par->niter,
+	   par->residual_before.bias,
+	   par->residual.bias,
+	   par->residual_before.first,
+	   par->residual.first,
+	   rate (par->residual.first,
+		 par->residual_before.first,
+		 par->niter),
+	   par->residual_before.second,
+	   par->residual.second,
+	   rate (par->residual.second,
+		 par->residual_before.second,
+		 par->niter),
+	   par->residual_before.infty,
+	   par->residual.infty,
+	   rate (par->residual.infty,
+		 par->residual_before.infty,
+		 par->niter));
+}
+
+typedef struct {
+  guint u, rhs, dia, res;
+  gint maxlevel;
+  gdouble beta, omega;
+  FttComponent component;
+  guint axi;
+} RelaxParams;
+
+static void relax (FttCell * cell, RelaxParams * p)
+{
+  GfsGradient g;
+  FttCellNeighbors neighbor;
+  FttCellFace f;
+  GfsGradient ng;
+
+  g.a = GFS_VARIABLE (cell, p->dia);
+  g.b = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    f.neighbor = neighbor.c[f.d];
+    if (f.neighbor) {
+      gfs_face_weighted_gradient (&f, &ng, p->u, p->maxlevel);
+      g.a += ng.a;
+      g.b += ng.b;
+    }
+  }
+  if (g.a > 0.)
+    GFS_VARIABLE (cell, p->u) = (g.b - GFS_VARIABLE (cell, p->rhs))/g.a;
+  else
+    GFS_VARIABLE (cell, p->u) = 0.;
+}
+
+static void relax2D (FttCell * cell, RelaxParams * p)
+{
+  GfsGradient g;
+  FttCellNeighbors neighbor;
+  FttCellFace f;
+  GfsGradient ng;
+
+  g.a = GFS_VARIABLE (cell, p->dia);
+  g.b = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (f.d = 0; f.d < FTT_NEIGHBORS_2D; f.d++) {
+    f.neighbor = neighbor.c[f.d];
+    if (f.neighbor) {
+      gfs_face_weighted_gradient_2D (&f, &ng, p->u, p->maxlevel);
+      g.a += ng.a;
+      g.b += ng.b;
+    }
+  }
+  if (g.a > 0.)
+    GFS_VARIABLE (cell, p->u) = 
+      (1. - p->omega)*GFS_VARIABLE (cell, p->u) 
+      + p->omega*(g.b - GFS_VARIABLE (cell, p->rhs))/g.a;
+  else
+    GFS_VARIABLE (cell, p->u) = 0.;
+}
+
+/**
+ * gfs_relax:
+ * @domain: the domain to relax.
+ * @d: number of dimensions (2 or 3).
+ * @max_depth: the maximum depth of the domain to relax.
+ * @u: the variable to use as left-hand side.
+ * @rhs: the variable to use as right-hand side.
+ * @dia: the diagonal weight.
+ *
+ * Apply one pass of a Jacobi relaxation to all the leaf cells of
+ * @domain with a level inferior or equal to @max_depth and to all the
+ * cells at level @max_depth. The relaxation should converge (if the
+ * right-hand-side @rhs verifies the solvability conditions) toward
+ * the solution of a Poisson equation for @u at the maximum depth.
+ */
+void gfs_relax (GfsDomain * domain,
+		guint d,
+		gint max_depth,
+		gdouble omega,
+		GfsVariable * u,
+		GfsVariable * rhs,
+		GfsVariable * dia)
+{
+  RelaxParams p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (d > 1 && d <= 3);
+  g_return_if_fail (u != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (dia != NULL);
+
+  p.u = u->i;
+  p.rhs = rhs->i;
+  p.dia = dia->i;
+  p.maxlevel = max_depth;
+  p.omega = omega;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+			    FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS,
+			    max_depth,
+			    (FttCellTraverseFunc) (d == 2 ? relax2D : relax), &p);
+}
+
+static void residual_set (FttCell * cell, RelaxParams * p)
+{
+  GfsGradient g;
+  FttCellNeighbors neighbor;
+  FttCellFace f;
+  GfsGradient ng;
+
+  g.a = GFS_VARIABLE (cell, p->dia);
+  g.b = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    f.neighbor = neighbor.c[f.d];
+    if (f.neighbor) {
+      gfs_face_weighted_gradient (&f, &ng, p->u, p->maxlevel);
+      g.a += ng.a;
+      g.b += ng.b;
+    }
+  }
+  GFS_VARIABLE (cell, p->res) = GFS_VARIABLE (cell, p->rhs) - 
+    (g.b - GFS_VARIABLE (cell, p->u)*g.a);
+}
+
+static void residual_set2D (FttCell * cell, RelaxParams * p)
+{
+  GfsGradient g;
+  FttCellNeighbors neighbor;
+  FttCellFace f;
+  GfsGradient ng;
+
+  g.a = GFS_VARIABLE (cell, p->dia);
+  g.b = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (f.d = 0; f.d < FTT_NEIGHBORS_2D; f.d++) {
+    f.neighbor = neighbor.c[f.d];
+    if (f.neighbor) {
+      gfs_face_weighted_gradient_2D (&f, &ng, p->u, p->maxlevel);
+      g.a += ng.a;
+      g.b += ng.b;
+    }
+  }
+  GFS_VARIABLE (cell, p->res) = GFS_VARIABLE (cell, p->rhs) - 
+    (g.b - GFS_VARIABLE (cell, p->u)*g.a);
+}
+
+/**
+ * gfs_residual:
+ * @domain: a domain.
+ * @d: number of dimensions (2 or 3).
+ * @flags: which types of cells are to be visited.
+ * @max_depth: maximum depth of the traversal.
+ * @u: the variable to use as left-hand side.
+ * @rhs: the variable to use as right-hand side.
+ * @dia: the diagonal weight.
+ * @res: the variable to use to store the residual.
+ *
+ * For each cell of @domain, computes the sum of the residual over
+ * the volume of the cell for a Poisson equation with @u as
+ * left-hand-side and @rhs as right-hand-side. Stores the result in
+ * @res.  
+ */
+void gfs_residual (GfsDomain * domain,
+		   guint d,
+		   FttTraverseFlags flags,
+		   gint max_depth,
+		   GfsVariable * u, GfsVariable * rhs, GfsVariable * dia,
+		   GfsVariable * res)
+{
+  RelaxParams p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (d > 1 && d <= 3);
+  g_return_if_fail (u != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (dia != NULL);
+  g_return_if_fail (res != NULL);
+
+  p.u = u->i;
+  p.rhs = rhs->i;
+  p.dia = dia->i;
+  p.res = res->i;
+  p.maxlevel = max_depth;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, flags, max_depth,
+			    (FttCellTraverseFunc) (d == 2 ? residual_set2D : residual_set), &p);
+}
+
+static void reset_coeff (FttCell * cell)
+{
+  FttDirection d;
+  GfsFaceStateVector * f = GFS_STATE (cell)->f;
+  
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    f[d].v = 0.;
+}
+
+typedef struct {
+  gdouble lambda2[FTT_DIMENSION];
+  GfsFunction * alpha;
+  GfsDomain * domain;
+} PoissonCoeff;
+
+static void poisson_coeff (FttCellFace * face,
+			   PoissonCoeff * p)
+{
+  gdouble alpha = p->alpha ? gfs_function_face_value (p->alpha, face) : 1.;
+  gdouble v = p->lambda2[face->d/2]*alpha*gfs_domain_face_fraction (p->domain, face);
+
+  if (alpha <= 0.) {
+    FttVector p;
+    ftt_face_pos (face, &p);
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	   "alpha is negative (%g) at face (%g,%g,%g).\n"
+	   "Please check your definition.",
+	   alpha, p.x, p.y, p.z);
+  }
+  GFS_STATE (face->cell)->f[face->d].v = v;
+  
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v = v;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v +=
+      v/FTT_CELLS_DIRECTION (face->d);
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void face_coeff_from_below (FttCell * cell)
+{
+  FttDirection d;
+  GfsFaceStateVector * f = GFS_STATE (cell)->f;
+  guint neighbors = 0;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    FttCellChildren child;
+    guint i, n;
+
+    f[d].v = 0.;
+    n = ftt_cell_children_direction (cell, d, &child);
+    for (i = 0; i < n; i++)
+      if (child.c[i])
+	f[d].v += GFS_STATE (child.c[i])->f[d].v;
+    f[d].v /= n;
+
+    FttCell * neighbor;
+    if (f[d].v > 0. && (neighbor = ftt_cell_neighbor (cell, d)) && !GFS_CELL_IS_BOUNDARY (neighbor))
+      neighbors++;
+  }
+
+  if (neighbors == 1)
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      f[d].v = 0.;
+}
+
+/**
+ * gfs_poisson_coefficients:
+ * @domain: a #GfsDomain.
+ * @alpha: the inverse of density or %NULL.
+ *
+ * Initializes the face coefficients for the Poisson equation
+ * $\nabla\cdot\alpha\nabla p=\dots$.
+ *
+ * If @alpha is %NULL, it is taken to be unity.
+ */
+void gfs_poisson_coefficients (GfsDomain * domain,
+			       GfsFunction * alpha)
+{
+  PoissonCoeff p;
+  FttComponent i;
+
+  g_return_if_fail (domain != NULL);
+
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    gdouble lambda = (&domain->lambda.x)[i];
+
+    p.lambda2[i] = lambda*lambda;
+  }
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) reset_coeff, NULL);
+  p.alpha = alpha;
+  p.domain = domain;
+  gfs_domain_face_traverse (domain, FTT_XYZ, 
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) poisson_coeff, &p);
+  gfs_domain_cell_traverse (domain,
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) face_coeff_from_below, NULL);
+}
+
+static void tension_coeff (FttCellFace * face, gpointer * data)
+{
+  gdouble * lambda2 = data[0];
+  GfsSourceTensionGeneric * t = data[1];
+  GfsVariable * kappa = GFS_SOURCE_TENSION (data[1])->k;
+  gdouble alpha = data[2] ? gfs_function_face_value (data[2], face) : 1.;
+  gdouble v = lambda2[face->d/2]*alpha*gfs_domain_face_fraction (kappa->domain, face)*
+    gfs_function_face_value (t->sigma, face);
+  gdouble k1 = GFS_VARIABLE (face->cell, kappa->i);
+  gdouble k2 = GFS_VARIABLE (face->neighbor, kappa->i);
+#if 0
+  gdouble c1 = GFS_VARIABLE (face->cell, t->c->i);
+  gdouble c2 = GFS_VARIABLE (face->neighbor, t->c->i);
+  gdouble w1 = c1*(1. - c1);
+  gdouble w2 = c2*(1. - c2);
+
+  if (w1 + w2 > 0.)
+    v *= (w1*k1 + w2*k2)/(w1 + w2);
+  else
+#endif
+  {
+    if (k1 < G_MAXDOUBLE) {
+      if (k2 < G_MAXDOUBLE)
+	v *= (k1 + k2)/2.;
+      else
+	v *= k1;
+    }
+    else if (k2 < G_MAXDOUBLE)
+      v *= k2;
+    else
+      v = 1e6;
+  }
+  g_assert (v <= 1e6);
+
+  if (alpha <= 0.) {
+    FttVector p;
+    ftt_face_pos (face, &p);
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	   "alpha is negative (%g) at face (%g,%g,%g).\n"
+	   "Please check your definition.",
+	   alpha, p.x, p.y, p.z);
+  }
+  GFS_STATE (face->cell)->f[face->d].v = v;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v = v;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v = G_MAXDOUBLE;
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+/**
+ * gfs_source_tension_coefficients:
+ * @s: a #GfsSourceTension.
+ * @domain: a #GfsDomain.
+ * @alpha: the inverse of density or %NULL.
+ *
+ * Initializes the face coefficients with the surface tension term
+ * (interface curvature times surface tension coefficient).
+ *
+ * If @alpha is %NULL, it is taken to be unity.
+ */
+void gfs_source_tension_coefficients (GfsSourceTension * s,
+				      GfsDomain * domain,
+				      GfsFunction * alpha)
+{
+  gdouble lambda2[FTT_DIMENSION];
+  gpointer data[3];
+  FttComponent i;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (domain != NULL);
+
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    gdouble lambda = (&domain->lambda.x)[i];
+
+    lambda2[i] = lambda*lambda;
+  }
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) reset_coeff, NULL);
+  data[0] = lambda2;
+  data[1] = s;
+  data[2] = alpha;
+  gfs_domain_face_traverse (domain, FTT_XYZ, 
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) tension_coeff, data);
+}
+
+static void correct (FttCell * cell, gpointer * data)
+{
+  GfsVariable * u = data[0];
+  GfsVariable * dp = data[1];
+  GFS_VALUE (cell, u) += GFS_VALUE (cell, dp);
+}
+
+static void get_from_above (FttCell * parent, GfsVariable * v)
+{
+  guint level = ftt_cell_level (parent);
+  FttCellNeighbors n;
+  FttCellChildren child;
+  FttComponent c;
+  FttVector h;
+  guint i;
+
+  ftt_cell_neighbors (parent, &n);
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    FttCellFace f;
+    GfsGradient g;
+    gdouble g1, g2;
+    
+    f.cell = parent;
+    f.d = 2*c;
+    f.neighbor = n.c[f.d];
+    gfs_face_gradient (&f, &g, v->i, level);
+    g1 = g.b - g.a*GFS_VARIABLE (parent, v->i);
+    f.d = 2*c + 1;
+    f.neighbor = n.c[f.d];
+    gfs_face_gradient (&f, &g, v->i, level);
+    g2 = g.b - g.a*GFS_VARIABLE (parent, v->i);
+    (&h.x)[c] = (g1 - g2)/2.;
+  }
+
+  ftt_cell_children (parent, &child);
+  for (i = 0; i < FTT_CELLS; i++) 
+    if (child.c[i]) {
+      FttVector p;
+      
+      GFS_VARIABLE (child.c[i], v->i) = GFS_VARIABLE (parent, v->i);
+      ftt_cell_relative_pos (child.c[i], &p);
+      for (c = 0; c < FTT_DIMENSION; c++)
+	GFS_VARIABLE (child.c[i], v->i) += (&p.x)[c]*(&h.x)[c];
+    }
+}
+
+static void get_from_below_3D (FttCell * cell, const GfsVariable * v)
+{
+  gdouble val = 0.;
+  guint i;
+  FttCellChildren child;
+
+  ftt_cell_children (cell, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i])
+      val += GFS_VARIABLE (child.c[i], v->i);
+  GFS_VARIABLE (cell, v->i) = val/2.;
+}
+
+static void get_from_below_2D (FttCell * cell, const GfsVariable * v)
+{
+  gdouble val = 0.;
+  guint i;
+  FttCellChildren child;
+
+  ftt_cell_children (cell, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i])
+      val += GFS_VARIABLE (child.c[i], v->i);
+  GFS_VARIABLE (cell, v->i) = val;
+}
+
+typedef struct {
+  GfsVariable * s, * r, * u, * v;
+  gdouble srs, rs2, beta;
+} MRSData;
+
+static void compute_beta (FttCell * cell, MRSData * data)
+{
+  gdouble rs = GFS_VALUE (cell, data->r) - GFS_VALUE (cell, data->s);
+  data->rs2 += rs*rs;
+  data->srs -= GFS_VALUE (cell, data->s)*rs;
+}
+
+static void update_sv (FttCell * cell, MRSData * data)
+{
+  GFS_VALUE (cell, data->s) += data->beta*(GFS_VALUE (cell, data->r) - GFS_VALUE (cell, data->s));
+  GFS_VALUE (cell, data->v) += data->beta*(GFS_VALUE (cell, data->u) - GFS_VALUE (cell, data->v));
+  GFS_VALUE (cell, data->r) = GFS_VALUE (cell, data->s);
+  GFS_VALUE (cell, data->u) = GFS_VALUE (cell, data->v);
+}
+
+static void relax_loop (GfsDomain * domain, 
+			GfsVariable * dp, GfsVariable * u, 
+			RelaxParams * q, guint nrelax,
+			guint dimension)
+{
+  guint n;
+  gfs_domain_homogeneous_bc (domain,
+			     FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, q->maxlevel, 
+			     dp, u);
+  for (n = 0; n < nrelax - 1; n++)
+    gfs_traverse_and_homogeneous_bc (domain, FTT_PRE_ORDER, 
+				     FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, q->maxlevel,
+				     (FttCellTraverseFunc) (dimension == 2 ? relax2D : relax), q,
+				     dp, u);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+			    FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, q->maxlevel,
+			    (FttCellTraverseFunc) (dimension == 2 ? relax2D : relax), q);
+}
+
+/**
+ * gfs_poisson_cycle:
+ * @domain: the domain on which to solve the Poisson equation.
+ * @p: the #GfsMultilevelParams.
+ * @u: the variable to use as left-hand side.
+ * @rhs: the variable to use as right-hand side.
+ * @dia: the diagonal weight.
+ * @res: the residual.
+ *
+ * Apply one multigrid iteration to the Poisson equation defined by @u
+ * and @rhs.
+ *
+ * The initial value of @res on the leaves of @root must be set to
+ * the residual of the Poisson equation (using gfs_residual()).
+ *
+ * The face coefficients must be set using gfs_poisson_coefficients().
+ *
+ * The values of @u on the leaf cells are updated as well as the values
+ * of @res (i.e. the cell tree is ready for another iteration).
+ */
+void gfs_poisson_cycle (GfsDomain * domain,
+			GfsMultilevelParams * p,
+			GfsVariable * u,
+			GfsVariable * rhs,
+			GfsVariable * dia,
+			GfsVariable * res)
+{
+  guint l, nrelax, minlevel;
+  GfsVariable * dp;
+  gpointer data[2];
+  
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (p->dimension > 1 && p->dimension <= 3);
+  g_return_if_fail (u != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (dia != NULL);
+  g_return_if_fail (res != NULL);
+
+  dp = gfs_temporary_variable (domain);
+  minlevel = MAX (domain->rootlevel, p->minlevel);
+
+  /* compute residual on non-leafs cells */
+  gfs_domain_cell_traverse (domain, 
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    p->dimension == 2 ? (FttCellTraverseFunc) get_from_below_2D : 
+			    (FttCellTraverseFunc) get_from_below_3D,
+			    res);
+
+  /* relax top level */
+  nrelax = p->nrelax;
+  for (l = minlevel; l < p->depth; l++)
+    nrelax *= p->erelax;
+
+  RelaxParams q;
+  q.u = dp->i;
+  q.rhs = res->i;
+  q.dia = dia->i;
+  q.maxlevel = minlevel;
+  q.omega = p->omega;
+  
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, q.maxlevel,
+			    (FttCellTraverseFunc) gfs_cell_reset, dp);
+  relax_loop (domain, dp, u, &q, nrelax, p->dimension);
+  nrelax /= p->erelax;
+
+  /* relax from top to bottom */
+  for (q.maxlevel = minlevel + 1; q.maxlevel <= p->depth; q.maxlevel++, nrelax /= p->erelax) {
+    /* get initial guess from coarser grid */ 
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_NON_LEAFS, 
+			      q.maxlevel - 1,
+			      (FttCellTraverseFunc) get_from_above, dp);
+    relax_loop (domain, dp, u, &q, nrelax, p->dimension);
+  }
+  /* correct on leaf cells */
+  data[0] = u;
+  data[1] = dp;
+  gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		       (FttCellTraverseFunc) correct, data,
+		       u, u);
+  /* compute new residual on leaf cells */
+  gfs_residual (domain, p->dimension, FTT_TRAVERSE_LEAFS, -1, u, rhs, dia, res);
+
+  gts_object_destroy (GTS_OBJECT (dp));
+}
+
+typedef struct {
+  GfsSourceDiffusion * d;
+  gdouble lambda2[FTT_DIMENSION];
+  gdouble dt;
+  GfsVariable * rhoc, * axi;
+  GfsFunction * alpha;
+  GfsDomain * domain;
+} DiffusionCoeff;
+
+static void diffusion_coef (FttCellFace * face, DiffusionCoeff * c)
+{
+  gdouble v = 
+    c->lambda2[face->d/2]*c->dt*
+    gfs_source_diffusion_face (c->d, face)*
+    gfs_domain_face_fraction (c->domain, face);
+
+  GFS_STATE (face->cell)->f[face->d].v = v;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v = v;
+    break;
+  case FTT_FINE_COARSE:
+    GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v +=
+      v/FTT_CELLS_DIRECTION (face->d);
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void diffusion_mixed_coef (FttCell * cell, DiffusionCoeff * c)
+{
+  reset_coeff (cell);
+  if (GFS_IS_MIXED (cell))
+    GFS_STATE (cell)->solid->v = 
+      c->dt*gfs_domain_solid_metric (c->domain, cell)*gfs_source_diffusion_cell (c->d, cell);
+  if (c->rhoc) {
+    gdouble rho = c->alpha ? 1./gfs_function_value (c->alpha, cell) : 1.;
+    if (rho <= 0.) {
+      FttVector p;
+      ftt_cell_pos (cell, &p);
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	     "density is negative (%g) at cell (%g,%g,%g).\n"
+	     "Please check your definition of alpha.",
+	     rho, p.x, p.y, p.z);
+    }
+    gdouble f = gfs_domain_cell_fraction (c->domain, cell);
+    GFS_VALUE (cell, c->rhoc) = rho*f;
+
+    if (c->axi) {
+      FttVector p;
+      gfs_cell_cm (cell, &p);
+      GFS_VALUE (cell, c->axi) = 2.*c->dt*gfs_source_diffusion_cell (c->d, cell)/(rho*p.y*p.y);
+    }
+  }
+}
+
+/**
+ * gfs_diffusion_coefficients:
+ * @domain: a #GfsDomain.
+ * @d: a #GfsSourceDiffusion.
+ * @dt: the time-step.
+ * @rhoc: where to store the mass.
+ * @axi: where to store the axisymmetric term (or %NULL).
+ * @alpha: the inverse of density or %NULL.
+ * @beta: the implicitness parameter (0.5 Crank-Nicholson, 1. backward Euler).
+ *
+ * Initializes the face coefficients for the diffusion equation.
+ */
+void gfs_diffusion_coefficients (GfsDomain * domain,
+				 GfsSourceDiffusion * d,
+				 gdouble dt,
+				 GfsVariable * rhoc,
+				 GfsVariable * axi,
+				 GfsFunction * alpha,
+				 gdouble beta)
+{
+  DiffusionCoeff coef;
+  FttComponent i;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (beta >= 0.5 && beta <= 1.);
+
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    gdouble lambda = (&domain->lambda.x)[i];
+
+    coef.lambda2[i] = lambda*lambda;
+  }
+  coef.d = d;
+  coef.dt = beta*dt;
+  coef.rhoc = rhoc;
+  coef.alpha = alpha;
+  coef.domain = domain;
+  coef.axi = axi;
+  gfs_domain_cell_traverse (domain,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) diffusion_mixed_coef, &coef);
+  gfs_domain_face_traverse (domain, FTT_XYZ, 
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) diffusion_coef, &coef);
+  gfs_domain_cell_traverse (domain,
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) face_coeff_from_below, 
+			    NULL);
+}
+
+static void diffusion_rhs (FttCell * cell, RelaxParams * p)
+{
+  gdouble f, h, val;
+  FttCellNeighbors neighbor;
+  FttCellFace face;
+  
+  if (GFS_IS_MIXED (cell)) {
+    if (((cell)->flags & GFS_FLAG_DIRICHLET) != 0)
+      f = gfs_cell_dirichlet_gradient_flux (cell, p->u, -1, GFS_STATE (cell)->solid->fv);
+    else
+      f = GFS_STATE (cell)->solid->fv;
+  }
+  else
+    f = 0.; /* Neumann condition by default */
+  h = ftt_cell_size (cell);
+  val = GFS_VARIABLE (cell, p->u);
+  face.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (face.d = 0; face.d < FTT_NEIGHBORS; face.d++) {
+    GfsGradient g;
+
+    face.neighbor = neighbor.c[face.d];
+    gfs_face_gradient_flux (&face, &g, p->u, -1);
+    if (face.d/2 == p->component) {
+      g.a *= 2.;
+      g.b *= 2.;
+    }
+    f += g.b - g.a*val;
+  }
+  GFS_VARIABLE (cell, p->rhs) += p->beta*f/(h*h*GFS_VARIABLE (cell, p->dia));
+  if (p->axi)
+    GFS_VARIABLE (cell, p->rhs) -= val*p->beta*GFS_VARIABLE (cell, p->axi);
+}
+
+/**
+ * gfs_diffusion_rhs:
+ * @domain: a #GfsDomain.
+ * @v: a #GfsVariable.
+ * @rhs: a #GfsVariable.
+ * @rhoc: the mass.
+ * @axi: the axisymmetric term.
+ * @beta: the implicitness parameter (0.5 Crank-Nicholson, 1. backward Euler).
+ *
+ * Adds to the @rhs variable of @cell the right-hand side of the
+ * diffusion equation for variable @v.
+ *
+ * The diffusion coefficients must have been already set using
+ * gfs_diffusion_coefficients().
+ */
+void gfs_diffusion_rhs (GfsDomain * domain, 
+			GfsVariable * v, GfsVariable * rhs, 
+			GfsVariable * rhoc, GfsVariable * axi,
+			gdouble beta)
+{
+  RelaxParams p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (rhoc != NULL);
+  g_return_if_fail (beta >= 0.5 && beta <= 1.);
+
+  p.u = v->i;
+  p.rhs = rhs->i;
+  p.dia = rhoc->i;
+  p.beta = (1. - beta)/beta;
+  p.component = GFS_IS_AXI (domain) ? v->component : FTT_DIMENSION;
+  p.axi = axi ? axi->i : FALSE;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) diffusion_rhs, &p);
+}
+
+static void diffusion_relax (FttCell * cell, RelaxParams * p)
+{
+  gdouble a;
+  GfsGradient g = { 0., 0. };
+  gdouble h = ftt_cell_size (cell);
+  FttCellNeighbors neighbor;
+  FttCellFace face;
+
+  a = GFS_VARIABLE (cell, p->dia);
+  if (GFS_IS_MIXED (cell) && ((cell)->flags & GFS_FLAG_DIRICHLET) != 0)
+    g.b = gfs_cell_dirichlet_gradient_flux (cell, p->u, p->maxlevel, 0.);
+
+  face.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (face.d = 0; face.d < FTT_NEIGHBORS; face.d++) {
+    GfsGradient ng;
+
+    face.neighbor = neighbor.c[face.d];
+    gfs_face_gradient_flux (&face, &ng, p->u, p->maxlevel);
+    if (face.d/2 == p->component) {
+      ng.a *= 2.;
+      ng.b *= 2.;
+    }
+    g.a += ng.a;
+    g.b += ng.b;
+  }
+  a *= h*h;
+  g_assert (a > 0.);
+  g.a = 1. + g.a/a;
+  if (p->axi)
+    g.a += GFS_VARIABLE (cell, p->axi);
+  g.b = GFS_VARIABLE (cell, p->res) + g.b/a;
+  g_assert (g.a > 0.);
+  GFS_VARIABLE (cell, p->u) = g.b/g.a;
+}
+
+static void diffusion_residual (FttCell * cell, RelaxParams * p)
+{
+  gdouble a;
+  GfsGradient g = { 0., 0. };
+  gdouble h;
+  FttCellNeighbors neighbor;
+  FttCellFace face;
+
+  h = ftt_cell_size (cell);
+  a = GFS_VARIABLE (cell, p->dia);
+  if (GFS_IS_MIXED (cell)) {
+    if (((cell)->flags & GFS_FLAG_DIRICHLET) != 0)
+      g.b = gfs_cell_dirichlet_gradient_flux (cell, p->u, -1, GFS_STATE (cell)->solid->fv);
+    else
+      g.b = GFS_STATE (cell)->solid->fv;
+  }
+
+  face.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (face.d = 0; face.d < FTT_NEIGHBORS; face.d++) {
+    GfsGradient ng;
+
+    face.neighbor = neighbor.c[face.d];
+    gfs_face_gradient_flux (&face, &ng, p->u, -1);
+    if (face.d/2 == p->component) {
+      ng.a *= 2.;
+      ng.b *= 2.;
+    }
+    g.a += ng.a;
+    g.b += ng.b;
+  }
+  a *= h*h;
+  g_assert (a > 0.);
+  g.a = 1. + g.a/a;
+  if (p->axi)
+    g.a += GFS_VARIABLE (cell, p->axi);
+  g.b = GFS_VARIABLE (cell, p->rhs) + g.b/a;
+  GFS_VARIABLE (cell, p->res) = g.b - g.a*GFS_VARIABLE (cell, p->u);
+}
+
+/**
+ * gfs_diffusion_residual:
+ * @domain: a #GfsDomain.
+ * @u: the variable to use as left-hand side.
+ * @rhs: the right-hand side.
+ * @rhoc: the mass.
+ * @axi: the axisymmetric term.
+ * @res: the residual.
+ *
+ * Sets the @res variable of each leaf cell of @domain to the residual
+ * of the diffusion equation for @v.
+ *
+ * The diffusion coefficients must have been set using
+ * gfs_diffusion_coefficients() and the right-hand side using
+ * gfs_diffusion_rhs().
+ */
+void gfs_diffusion_residual (GfsDomain * domain,
+			     GfsVariable * u,
+			     GfsVariable * rhs,
+			     GfsVariable * rhoc,
+			     GfsVariable * axi,
+			     GfsVariable * res)
+{
+  RelaxParams p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (u != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (rhoc != NULL);
+  g_return_if_fail (res != NULL);
+
+  p.u = u->i;
+  p.rhs = rhs->i;
+  p.dia = rhoc->i;
+  p.res = res->i;
+  p.component = GFS_IS_AXI (domain) ? u->component : FTT_DIMENSION;
+  p.axi = axi ? axi->i : FALSE;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) diffusion_residual, &p);
+}
+
+static void diffusion_relax_loop (GfsDomain * domain, 
+				  GfsVariable * dp, GfsVariable * u,
+				  RelaxParams * p, guint nrelax)
+{
+  guint n;
+  gfs_domain_homogeneous_bc (domain, 
+			     FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, p->maxlevel,
+			     dp, u);
+  for (n = 0; n < nrelax - 1; n++)
+    gfs_traverse_and_homogeneous_bc (domain, FTT_PRE_ORDER, 
+				     FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, p->maxlevel,
+				     (FttCellTraverseFunc) diffusion_relax, p,
+				     dp, u);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, 
+			    FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, p->maxlevel,
+			    (FttCellTraverseFunc) diffusion_relax, p);
+}
+
+/**
+ * gfs_diffusion_cycle:
+ * @domain: the domain on which to solve the diffusion equation.
+ * @levelmin: the top level of the multigrid hierarchy.
+ * @depth: the total depth of the domain.
+ * @nrelax: the number of relaxations to apply at each level.
+ * @u: the variable to use as left-hand side.
+ * @rhs: the right-hand side.
+ * @rhoc: the mass.
+ * @axi: the axisymmetric term.
+ * @res: the residual.
+ *
+ * Apply one multigrid iteration to the diffusion equation for @u.
+ *
+ * The initial value of @res on the leaves of @root must be set to
+ * the residual of the diffusion equation using gfs_diffusion_residual().
+ *
+ * The diffusion coefficients must be set using gfs_diffusion_coefficients().
+ *
+ * The values of @u on the leaf cells are updated as well as the values
+ * of @res (i.e. the cell tree is ready for another iteration).
+ */
+void gfs_diffusion_cycle (GfsDomain * domain,
+			  guint levelmin,
+			  guint depth,
+			  guint nrelax,
+			  GfsVariable * u,
+			  GfsVariable * rhs,
+			  GfsVariable * rhoc,
+			  GfsVariable * axi,
+			  GfsVariable * res)
+{
+  GfsVariable * dp;
+  RelaxParams p;
+  gpointer data[2];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (u != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (rhoc != NULL);
+  g_return_if_fail (res != NULL);
+
+  dp = gfs_temporary_variable (domain);
+  dp->component = u->component;
+
+  /* compute residual on non-leafs cells */
+  gfs_domain_cell_traverse (domain, 
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) gfs_get_from_below_intensive, res);
+
+  /* relax top level */
+  p.maxlevel = levelmin;
+  p.u = dp->i;
+  p.res = res->i;
+  p.dia = rhoc->i;
+  p.component = GFS_IS_AXI (domain) ? u->component : FTT_DIMENSION;
+  p.axi = axi ? axi->i : FALSE;
+
+  gfs_domain_cell_traverse (domain, 
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, levelmin,
+			    (FttCellTraverseFunc) gfs_cell_reset, dp);
+  diffusion_relax_loop (domain, dp, u, &p, 10*nrelax);
+  /* relax from top to bottom */
+  for (p.maxlevel = levelmin + 1; p.maxlevel <= depth; p.maxlevel++) {
+    /* get initial guess from coarser grid */ 
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_NON_LEAFS,
+			      p.maxlevel - 1,
+			      (FttCellTraverseFunc) get_from_above, dp);
+    diffusion_relax_loop (domain, dp, u, &p, nrelax);
+  }
+  /* correct on leaf cells */
+  data[0] = u;
+  data[1] = dp;
+  gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		       (FttCellTraverseFunc) correct, data,
+		       u, u);
+  /* compute new residual on leaf cells */
+  gfs_diffusion_residual (domain, u, rhs, rhoc, axi, res);
+
+  gts_object_destroy (GTS_OBJECT (dp));
+}
+
diff --git a/src/poisson.h b/src/poisson.h
new file mode 100644
index 0000000..900782b
--- /dev/null
+++ b/src/poisson.h
@@ -0,0 +1,110 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __POISSON_H__
+#define __POISSON_H__
+
+#include <gts.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "domain.h"
+
+typedef struct _GfsMultilevelParams GfsMultilevelParams;
+
+struct _GfsMultilevelParams {
+  gdouble tolerance;
+  guint nrelax, erelax;
+  guint minlevel;
+  guint nitermax, nitermin;
+
+  guint dimension;
+  guint niter;
+  guint depth;
+  gboolean weighted;
+  gdouble beta, omega;
+  GfsNorm residual_before, residual;
+};
+
+void                  gfs_multilevel_params_init     (GfsMultilevelParams * par);
+void                  gfs_multilevel_params_write    (GfsMultilevelParams * par, 
+						      FILE * fp);
+void                  gfs_multilevel_params_read     (GfsMultilevelParams * par, 
+						      GtsFile * fp);
+void                  gfs_multilevel_params_stats_write (GfsMultilevelParams * par,
+							 FILE * fp);
+void                  gfs_relax                      (GfsDomain * domain,
+						      guint d,
+						      gint max_depth,
+						      gdouble omega,
+						      GfsVariable * u,
+						      GfsVariable * rhs,
+						      GfsVariable * dia);
+void                  gfs_residual                   (GfsDomain * domain,
+						      guint d,
+						      FttTraverseFlags flags,
+						      gint max_depth,
+						      GfsVariable * u,
+						      GfsVariable * rhs,
+						      GfsVariable * dia,
+						      GfsVariable * res);
+void                  gfs_poisson_coefficients       (GfsDomain * domain,
+						      GfsFunction * alpha);
+void                  gfs_poisson_cycle              (GfsDomain * domain,
+						      GfsMultilevelParams * p,
+						      GfsVariable * u,
+						      GfsVariable * rhs,
+						      GfsVariable * dia,
+						      GfsVariable * res);
+void                  gfs_diffusion_coefficients     (GfsDomain * domain,
+						      GfsSourceDiffusion * d,
+						      gdouble dt,
+						      GfsVariable * rhoc,
+						      GfsVariable * axi,
+						      GfsFunction * alpha,
+						      gdouble beta);
+void                  gfs_diffusion_rhs              (GfsDomain * domain,
+						      GfsVariable * v,
+						      GfsVariable * rhs,
+						      GfsVariable * rhoc,
+						      GfsVariable * axi,
+						      gdouble beta);
+void                  gfs_diffusion_residual         (GfsDomain * domain,
+						      GfsVariable * u,
+						      GfsVariable * rhs,
+						      GfsVariable * rhoc,
+						      GfsVariable * axi,
+						      GfsVariable * res);
+void                  gfs_diffusion_cycle            (GfsDomain * domain,
+						      guint levelmin,
+						      guint depth,
+						      guint nrelax,
+						      GfsVariable * u,
+						      GfsVariable * rhs,
+						      GfsVariable * rhoc,
+						      GfsVariable * axi,
+						      GfsVariable * res);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __POISSON_H__ */
diff --git a/src/refine.c b/src/refine.c
new file mode 100644
index 0000000..22ed858
--- /dev/null
+++ b/src/refine.c
@@ -0,0 +1,523 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "refine.h"
+#include "solid.h"
+#include "adaptive.h"
+
+/* GfsRefine: Object */
+
+static gboolean refine_maxlevel (FttCell * cell, GfsFunction * maxlevel)
+{
+  return (ftt_cell_level (cell) < gfs_function_value (maxlevel, cell));
+}
+
+static void refine_box (GfsBox * box, GfsFunction * maxlevel)
+{
+  ftt_cell_refine (box->root, 
+		   (FttCellRefineFunc) refine_maxlevel, maxlevel,
+		   (FttCellInitFunc) gfs_cell_fine_init, gfs_box_domain (box));
+}
+
+static void gfs_refine_refine (GfsRefine * refine, GfsSimulation * sim)
+{
+  gts_container_foreach (GTS_CONTAINER (sim),
+			 (GtsFunc) refine_box, refine->maxlevel);
+}
+
+static void gfs_refine_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_REFINE (o)->maxlevel));
+  (* GTS_OBJECT_CLASS (gfs_refine_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_refine_write (GtsObject * object, FILE * fp)
+{
+  fprintf (fp, "%s", object->klass->info.name);
+  gfs_function_write (GFS_REFINE (object)->maxlevel, fp);
+}
+
+static void gfs_refine_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsRefine * refine = GFS_REFINE (*o);
+  GtsObjectClass * klass;
+  gboolean class_changed = FALSE;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsRefineClass)");
+    return;
+  }
+  klass = gfs_object_class_from_name (fp->token->str);
+  if (klass == NULL) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_refine_class ())) {
+    gts_file_error (fp, "`%s' is not a GfsRefine", fp->token->str);
+    return;
+  }
+  if (klass != (*o)->klass) {
+    *o = gts_object_new (klass);
+    gts_object_destroy (GTS_OBJECT (refine));
+    refine = GFS_REFINE (*o);
+    class_changed = TRUE;
+  }
+  gts_file_next_token (fp);
+
+  gfs_function_read (refine->maxlevel, gfs_object_simulation (refine), fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (class_changed && fp->type != '\n' && klass->read)
+    (* klass->read) (o, fp);
+}
+
+static void gfs_refine_class_init (GfsRefineClass * klass)
+{
+  klass->refine = gfs_refine_refine;
+
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_refine_destroy;
+  GTS_OBJECT_CLASS (klass)->write = gfs_refine_write;
+  GTS_OBJECT_CLASS (klass)->read =  gfs_refine_read;
+}
+
+static void gfs_refine_init (GfsRefine * object)
+{
+  object->maxlevel = gfs_function_new (gfs_function_class (), 1.);
+}
+
+GfsRefineClass * gfs_refine_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_info = {
+      "GfsRefine",
+      sizeof (GfsRefine),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_class_init,
+      (GtsObjectInitFunc) gfs_refine_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
+			    &gfs_refine_info);
+  }
+
+  return klass;
+}
+
+GfsRefine * gfs_refine_new (GfsRefineClass * klass)
+{
+  GfsRefine * object;
+
+  object = GFS_REFINE (gts_object_new (GTS_OBJECT_CLASS (klass)));
+
+  return object;
+}
+
+/* GfsRefineSolid: Object */
+
+typedef struct _GfsRefineSolid           GfsRefineSolid;
+
+struct _GfsRefineSolid {
+  GfsRefine parent;
+
+  GfsDerivedVariable * v;
+};
+  
+#define GFS_REFINE_SOLID(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsRefineSolid,\
+					           gfs_refine_solid_class ())
+
+static void refine_solid_destroy (GtsObject * object)
+{
+  gfs_domain_remove_derived_variable (GFS_DOMAIN (gfs_object_simulation (object)), 
+				      "SolidCurvature");
+
+  (* GTS_OBJECT_CLASS (gfs_refine_solid_class ())->parent_class->destroy) (object);
+}
+
+typedef struct {
+  GtsSurface * s;
+  gdouble kappa;
+} KappaData;
+
+static void max_kappa (GtsVertex * v, KappaData * d)
+{
+  GtsVector Kh;
+
+  if (gts_vertex_mean_curvature_normal (v, d->s, Kh)) {
+    gdouble kappa = gts_vector_norm (Kh)/(FTT_DIMENSION - 1);
+    if (kappa > d->kappa)
+      d->kappa = kappa;
+  }
+}
+
+static gdouble solid_curvature (FttCell * cell, FttCellFace * face, 
+				GfsDomain * domain, GfsGenericSurface * s)
+{
+  KappaData d;
+  d.kappa = gfs_solid_is_thin (cell, s) ? 1./ftt_cell_size (cell) : 0.;
+  d.s = GFS_SURFACE (s)->s;
+  gts_surface_foreach_vertex (d.s, (GtsFunc) max_kappa, &d);
+  return d.kappa;
+}
+
+static void refine_solid_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsRefineSolid * refine = GFS_REFINE_SOLID (*o);
+  GfsDerivedVariableInfo v = { "SolidCurvature", "curvature of the solid boundary",
+			       solid_curvature };
+  refine->v = gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v);
+  if (!refine->v) {
+    gts_file_error (fp, "derived variable `SolidCurvature' already defined");
+    return;
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_refine_solid_class ())->parent_class->read) (o, fp);
+}
+
+typedef struct {
+  GfsRefine * refine;
+  GfsDomain * domain;
+  GfsGenericSurface * surface;
+} RefineCut;
+
+static void refine_cut_cell (FttCell * cell, GfsGenericSurface * s, RefineCut * p)
+{
+  GTS_OBJECT (s)->reserved = p->surface;
+  GFS_REFINE_SOLID (p->refine)->v->data = s;
+  if (ftt_cell_level (cell) < gfs_function_value (p->refine->maxlevel, cell))
+    ftt_cell_refine_single (cell, p->domain->cell_init, p->domain->cell_init_data);
+  GFS_REFINE_SOLID (p->refine)->v->data = NULL;
+}
+
+static void refine_implicit_cell (FttCell * cell, RefineCut * p)
+{
+  guint maxlevel = gfs_function_value (p->refine->maxlevel, cell);
+  if (ftt_cell_level (cell) < maxlevel && gfs_cell_is_cut (cell, p->surface, FALSE, maxlevel))
+    ftt_cell_refine_single (cell, p->domain->cell_init, p->domain->cell_init_data);
+}
+
+static void gfs_refine_solid_refine (GfsRefine * refine, GfsSimulation * sim)
+{
+  if (sim->solids) {
+    RefineCut p;
+    p.refine = refine;
+    p.domain = GFS_DOMAIN (sim);
+    GSList * i = sim->solids->items;
+    while (i) {
+      p.surface = GFS_SOLID (i->data)->s;
+      if (GFS_SURFACE (p.surface)->s)
+	gfs_domain_traverse_cut (GFS_DOMAIN (sim), p.surface,
+				 FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				 (FttCellTraverseCutFunc) refine_cut_cell, &p);
+      else
+	gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) refine_implicit_cell, &p);
+      i = i->next;
+    }
+  }
+}
+
+static void gfs_refine_solid_class_init (GfsRefineClass * klass)
+{
+  klass->refine = gfs_refine_solid_refine;
+  GTS_OBJECT_CLASS (klass)->destroy = refine_solid_destroy;
+  GTS_OBJECT_CLASS (klass)->read = refine_solid_read;
+}
+
+GfsRefineClass * gfs_refine_solid_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_solid_info = {
+      "GfsRefineSolid",
+      sizeof (GfsRefineSolid),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_solid_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_refine_class ()),
+				  &gfs_refine_solid_info);
+  }
+
+  return klass;
+}
+
+/* GfsRefineSurface: Object */
+
+static void refine_surface_destroy (GtsObject * object)
+{
+  GfsRefineSurface * d = GFS_REFINE_SURFACE (object);
+
+  gts_object_destroy (GTS_OBJECT (d->surface));
+
+  (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->destroy) (object);
+}
+
+static void refine_surface_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->write) (o, fp);
+  gfs_generic_surface_write (GFS_REFINE_SURFACE (o)->surface, gfs_object_simulation (o), fp);
+}
+
+static void refine_surface_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_refine_surface_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_generic_surface_read (GFS_REFINE_SURFACE (*o)->surface, gfs_object_simulation (*o), fp);
+}
+
+static void gfs_refine_surface_refine (GfsRefine * refine, GfsSimulation * sim)
+{
+  RefineCut p;
+
+  p.refine = refine;
+  p.domain = GFS_DOMAIN (sim);
+  p.surface = GFS_REFINE_SURFACE (refine)->surface;
+  if (GFS_SURFACE (p.surface)->twod) {
+    if (GFS_SURFACE (p.surface)->s)
+      gfs_domain_traverse_cut_2D (GFS_DOMAIN (sim), GFS_REFINE_SURFACE (refine)->surface,
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				  (FttCellTraverseCutFunc) refine_cut_cell, &p);
+    else
+      g_assert_not_implemented ();
+  }
+  else {
+    if (GFS_SURFACE (p.surface)->s)
+      gfs_domain_traverse_cut (GFS_DOMAIN (sim), GFS_REFINE_SURFACE (refine)->surface,
+			       FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			       (FttCellTraverseCutFunc) refine_cut_cell, &p);
+    else
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) refine_implicit_cell, &p);
+  }
+}
+
+static void gfs_refine_surface_class_init (GfsRefineClass * klass)
+{
+  klass->refine = gfs_refine_surface_refine;
+
+  GTS_OBJECT_CLASS (klass)->destroy = refine_surface_destroy;
+  GTS_OBJECT_CLASS (klass)->write = refine_surface_write;
+  GTS_OBJECT_CLASS (klass)->read = refine_surface_read;
+}
+
+static void refine_surface_init (GfsRefineSurface * r)
+{
+  r->surface = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+}
+
+GfsRefineClass * gfs_refine_surface_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_surface_info = {
+      "GfsRefineSurface",
+      sizeof (GfsRefineSurface),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_surface_class_init,
+      (GtsObjectInitFunc) refine_surface_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_refine_class ()),
+				  &gfs_refine_surface_info);
+  }
+
+  return klass;
+}
+
+/* GfsRefineDistance: Object */
+
+static void refine_distance_destroy (GtsObject * object)
+{
+  GfsRefineDistance * d = GFS_REFINE_DISTANCE (object);
+
+  if (d->stree)
+    gts_bb_tree_destroy (d->stree, TRUE);
+  gfs_domain_remove_derived_variable (GFS_DOMAIN (gfs_object_simulation (object)), "Distance");
+
+  (* GTS_OBJECT_CLASS (gfs_refine_distance_class ())->parent_class->destroy) (object);
+}
+
+static gdouble cell_distance (FttCell * cell, 
+			      FttCellFace * face, 
+			      GfsSimulation * sim,
+			      GfsRefineDistance * refine)
+{
+  FttVector pos;
+  gdouble h = GFS_DIAGONAL*ftt_cell_size (cell), d;
+  GtsPoint p;
+
+  ftt_cell_pos (cell, &pos);
+  p.x = pos.x; p.y = pos.y; p.z = pos.z;
+  d = gts_bb_tree_point_distance (refine->stree, &p,
+				  (GtsBBoxDistFunc) gts_point_triangle_distance, NULL);
+  return d > h ? d - h : 0.;
+}
+
+static void refine_distance_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDerivedVariableInfo v = { "Distance", "distance to the surface", 
+			       cell_distance };
+
+  v.data = *o;
+  if (!gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v)) {
+    gts_file_error (fp, "derived variable `Distance' already defined");
+    return;
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_refine_distance_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GtsSurface * s = GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s;
+  if (!s) {
+    gts_file_error (fp, "RefineDistance only works with GTS surfaces");
+    return;
+  }
+
+  GFS_REFINE_DISTANCE (*o)->stree = gts_bb_tree_surface (s);
+}
+
+static void gfs_refine_distance_class_init (GfsRefineClass * klass)
+{
+  klass->refine = gfs_refine_refine;
+
+  GTS_OBJECT_CLASS (klass)->destroy = refine_distance_destroy;
+  GTS_OBJECT_CLASS (klass)->read = refine_distance_read;
+}
+
+GfsRefineClass * gfs_refine_distance_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_distance_info = {
+      "GfsRefineDistance",
+      sizeof (GfsRefineDistance),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_distance_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_refine_surface_class ()),
+				  &gfs_refine_distance_info);
+  }
+
+  return klass;
+}
+
+/* GfsRefineHeight: Object */
+
+static void refine_height_destroy (GtsObject * object)
+{
+  gfs_domain_remove_derived_variable (GFS_DOMAIN (gfs_object_simulation (object)), "Height");
+
+  (* GTS_OBJECT_CLASS (gfs_refine_height_class ())->parent_class->destroy) (object);
+}
+
+static gdouble interpolated_value (GtsSurface * s, FttVector * p)
+{
+  GtsPoint q;
+  GtsFace * t;
+
+  q.x = p->x; q.y = p->y;
+  t = gts_point_locate (&q, s, NULL);
+  if (t == NULL) {
+    g_warning ("cannot locate point (%g,%g)", p->x, p->y);
+    return 0.;
+  }
+  gts_triangle_interpolate_height (GTS_TRIANGLE (t), &q);
+  return q.z;
+}
+
+static gdouble cell_height (FttCell * cell, 
+			    FttCellFace * face, 
+			    GfsSimulation * sim,
+			    GfsRefineSurface * refine)
+{
+  FttVector pos;
+  ftt_cell_pos (cell, &pos);
+  return interpolated_value (GFS_SURFACE (refine->surface)->s, &pos);
+}
+
+static void refine_height_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDerivedVariableInfo v = { "Height", "vertical distance to the surface", 
+			       cell_height };
+
+  v.data = *o;
+  if (!gfs_domain_add_derived_variable (GFS_DOMAIN (gfs_object_simulation (*o)), v)) {
+    gts_file_error (fp, "derived variable `Height' already defined");
+    return;
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_refine_height_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (!GFS_SURFACE (GFS_REFINE_SURFACE (*o)->surface)->s) {
+    gts_file_error (fp, "RefineHeight only works with GTS surfaces");
+    return;
+  }
+}
+
+static void gfs_refine_height_class_init (GfsRefineClass * klass)
+{
+  klass->refine = gfs_refine_refine;
+
+  GTS_OBJECT_CLASS (klass)->destroy = refine_height_destroy;
+  GTS_OBJECT_CLASS (klass)->read = refine_height_read;
+}
+
+GfsRefineClass * gfs_refine_height_class (void)
+{
+  static GfsRefineClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_refine_height_info = {
+      "GfsRefineHeight",
+      sizeof (GfsRefineSurface),
+      sizeof (GfsRefineClass),
+      (GtsObjectClassInitFunc) gfs_refine_height_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_refine_surface_class ()),
+				  &gfs_refine_height_info);
+  }
+
+  return klass;
+}
diff --git a/src/refine.h b/src/refine.h
new file mode 100644
index 0000000..a5f9cfe
--- /dev/null
+++ b/src/refine.h
@@ -0,0 +1,118 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __REFINE_H__
+#define __REFINE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "simulation.h"
+
+#if FTT_2D
+# define GFS_DIAGONAL 0.707106781187
+#else /* 3D */
+# define GFS_DIAGONAL 0.866025403785
+#endif /* 3D */
+
+/* GfsRefine: Header */
+
+typedef struct _GfsRefine             GfsRefine;
+typedef struct _GfsRefineClass        GfsRefineClass;
+
+struct _GfsRefine {
+  GtsSListContainee parent;
+
+  GfsFunction * maxlevel;
+};
+
+struct _GfsRefineClass {
+  GtsSListContaineeClass parent_class;
+
+  void (* refine) (GfsRefine * refine, GfsSimulation * simulation);
+};
+
+#define GFS_REFINE(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsRefine,\
+					           gfs_refine_class ())
+#define GFS_REFINE_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsRefineClass,\
+						   gfs_refine_class())
+#define GFS_IS_REFINE(obj)         (gts_object_is_from_class (obj,\
+						   gfs_refine_class ()))
+     
+GfsRefineClass * gfs_refine_class  (void);
+GfsRefine *      gfs_refine_new    (GfsRefineClass * klass);
+
+/* GfsRefineSolid: Header */
+
+#define GFS_IS_REFINE_SOLID(obj)         (gts_object_is_from_class (obj,\
+						   gfs_refine_solid_class ()))
+     
+GfsRefineClass * gfs_refine_solid_class  (void);
+
+/* GfsRefineSurface: Header */
+
+typedef struct _GfsRefineSurface         GfsRefineSurface;
+
+struct _GfsRefineSurface {
+  GfsRefine parent;
+
+  GfsGenericSurface * surface;
+};
+
+#define GFS_REFINE_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsRefineSurface,\
+					           gfs_refine_surface_class ())
+#define GFS_IS_REFINE_SURFACE(obj)         (gts_object_is_from_class (obj,\
+						   gfs_refine_surface_class ()))
+     
+GfsRefineClass * gfs_refine_surface_class  (void);
+
+/* GfsRefineDistance: Header */
+
+typedef struct _GfsRefineDistance         GfsRefineDistance;
+
+struct _GfsRefineDistance {
+  GfsRefineSurface parent;
+
+  GNode * stree;
+};
+
+#define GFS_REFINE_DISTANCE(obj)            GTS_OBJECT_CAST (obj,\
+					          GfsRefineDistance,\
+					          gfs_refine_distance_class ())
+#define GFS_IS_REFINE_DISTANCE(obj)         (gts_object_is_from_class (obj,\
+						  gfs_refine_distance_class ()))
+     
+GfsRefineClass * gfs_refine_distance_class  (void);
+
+/* GfsRefineHeight: Header */
+
+#define GFS_IS_REFINE_HEIGHT(obj)         (gts_object_is_from_class (obj,\
+						  gfs_refine_height_class ()))
+     
+GfsRefineClass * gfs_refine_height_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __REFINE_H__ */
diff --git a/src/river.c b/src/river.c
new file mode 100644
index 0000000..c4ca052
--- /dev/null
+++ b/src/river.c
@@ -0,0 +1,627 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "river.h"
+#include "adaptive.h"
+#include "source.h"
+
+/* GfsRiver: Object */
+
+static void flux (const gdouble * u, gdouble g, gdouble * f)
+{
+  f[0] = u[0]*u[1];                                     /* h*u */
+  f[1] = u[0]*u[1]*u[1] + g*(u[0]*u[0] - u[3]*u[3])/2.; /* h*u*u + g*(h*h - zb*zb)/2 */
+  f[2] = u[0]*u[1]*u[2];                                /* h*u*v */
+}
+
+static gdouble min (gdouble a, gdouble b)
+{
+  return a < b ? a : b;
+}
+
+static gdouble max (gdouble a, gdouble b)
+{
+  return a > b ? a : b;
+}
+
+/*
+ * uL: left state vector [h,u,v,zb].
+ * uR: right state vector.
+ * g: acceleration of gravity.
+ * f: flux vector.
+ *
+ * Fills @f by solving an approximate Riemann problem using the HLLC
+ * scheme. See e.g. Liang, Borthwick, Stelling, IJNMF, 2004.
+ */
+static void riemann_hllc (const gdouble * uL, const gdouble * uR,
+			  gdouble g,
+			  gdouble * f)
+{
+  gdouble cL = sqrt (g*uL[0]), cR = sqrt (g*uR[0]);
+  gdouble ustar = (uL[1] + uR[1])/2. + cL - cR;
+  gdouble cstar = (cL + cR)/2. + (uL[1] - uR[1])/4.;
+  gdouble SL = uL[0] == 0. ? uR[1] - 2.*cR : min (uL[1] - cL, ustar - cstar);
+  gdouble SR = uR[0] == 0. ? uL[1] + 2.*cL : max (uR[1] + cR, ustar + cstar);
+
+  if (0. <= SL)
+    flux (uL, g, f);
+  else if (0. >= SR)
+    flux (uR, g, f);
+  else {
+    gdouble fL[3], fR[3];
+    flux (uL, g, fL);
+    flux (uR, g, fR);
+    f[0] = (SR*fL[0] - SL*fR[0] + SL*SR*(uR[0] - uL[0]))/(SR - SL);
+    f[1] = (SR*fL[1] - SL*fR[1] + SL*SR*(uR[0]*uR[1] - uL[0]*uL[1]))/(SR - SL);
+    gdouble SM = ((SL*uR[0]*(uR[1] - SR) - SR*uL[0]*(uL[1] - SL))/
+		  (uR[0]*(uR[1] - SR) - uL[0]*(uL[1] - SL)));
+    if (SL <= 0. && 0. <= SM)
+      f[2] = uL[2]*f[0];
+    else if (SM <= 0. && 0. <= SR)
+      f[2] = uR[2]*f[0];
+    else {
+      fprintf (stderr, "L: %g %g %g R: %g %g %g\n",
+	       uL[0], uL[1], uL[2],
+	       uR[0], uR[1], uR[2]);
+      fprintf (stderr, "SL: %g SR: %g SM: %g\n", SL, SR, SM);
+      g_assert_not_reached ();
+    }
+  }
+}
+
+#define U 1
+#define V 2
+
+typedef struct {
+  FttComponent u;
+  gdouble du;
+  FttComponent v;
+  gdouble dv;
+} Sym;
+
+static void face_fluxes (FttCellFace * face, GfsRiver * r)
+{
+  if (GFS_VALUE (face->cell, r->v1[0]) <= GFS_RIVER_DRY &&
+      GFS_VALUE (face->neighbor, r->v1[0]) <= GFS_RIVER_DRY)
+    return;
+
+  static Sym sym[4] = {
+    {U,  1., V,  1.},
+    {U, -1., V, -1.},
+    {V,  1., U, -1.},
+    {V, -1., U,  1.}
+  };
+  Sym * s = &sym[face->d];
+  gdouble etaL = (GFS_VALUE (face->cell, r->v1[0]) + 
+		  s->du*GFS_VALUE (face->cell, r->dv[face->d/2][0]));
+  gdouble zbL = (GFS_VALUE (face->cell, r->v[3]) + 
+		 s->du*GFS_VALUE (face->cell, r->dv[face->d/2][3]));
+  gdouble zbR = (GFS_VALUE (face->neighbor, r->v[3]) -
+		 s->du*GFS_VALUE (face->neighbor, r->dv[face->d/2][3]));
+  gdouble zbLR = MAX (zbL, zbR);
+  gdouble uL[4], uR[4], f[3];
+
+  if (etaL > GFS_RIVER_DRY) {
+    uL[1] = s->du*(GFS_VALUE (face->cell, r->v1[s->u]) +
+		   s->du*GFS_VALUE (face->cell, r->dv[face->d/2][s->u]))/etaL; /* u = uh/h */
+    uL[2] = s->dv*(GFS_VALUE (face->cell, r->v1[s->v]) +
+		   s->du*GFS_VALUE (face->cell, r->dv[face->d/2][s->v]))/etaL; /* v = vh/h */
+  }
+  else
+    uL[1] = uL[2] = 0.;
+  uL[0] = MAX (0., etaL + zbL - zbLR);
+  uL[3] = 0.;
+
+  gdouble etaR = (GFS_VALUE (face->neighbor, r->v1[0]) -
+		  s->du*GFS_VALUE (face->neighbor, r->dv[face->d/2][0]));
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE: case FTT_FINE_COARSE:
+    /* fixme: this is only first-order accurate for fine/coarse */
+    if (etaR > GFS_RIVER_DRY) {
+      uR[1] = s->du*(GFS_VALUE (face->neighbor, r->v1[s->u]) -
+		     s->du*GFS_VALUE (face->neighbor, r->dv[face->d/2][s->u]))/etaR; /* u = uh/h */
+      uR[2] = s->dv*(GFS_VALUE (face->neighbor, r->v1[s->v]) -
+		     s->du*GFS_VALUE (face->neighbor, r->dv[face->d/2][s->v]))/etaR; /* v = vh/h */
+    }
+    else
+      uR[1] = uR[2] = 0.;
+    uR[0] = MAX (0., etaR + zbR - zbLR);
+    uR[3] = 0.;
+    break;
+
+  default:
+    g_assert_not_reached ();
+  }
+
+  riemann_hllc (uL, uR, r->g, f);
+
+  gdouble dt = gfs_domain_face_fraction (r->v[0]->domain, face)*r->dt/ftt_cell_size (face->cell);
+  f[0] *= dt;
+  f[2] = s->dv*dt*f[2];
+  GFS_VALUE (face->cell, r->flux[0])    -= f[0];
+  /* see equation 2.16 of Audusse et al, 2004 */
+  GFS_VALUE (face->cell, r->flux[s->u]) -= s->du*dt*(f[1] - r->g/2.*(uL[0]*uL[0] - etaL*etaL));
+  GFS_VALUE (face->cell, r->flux[s->v]) -= f[2];
+
+  f[1] = s->du*dt*(f[1] - r->g/2.*(uR[0]*uR[0] - etaR*etaR));
+  if (ftt_face_type (face) == FTT_FINE_COARSE) {
+    f[0] /= FTT_CELLS;
+    f[1] /= FTT_CELLS;
+    f[2] /= FTT_CELLS;
+  }
+  GFS_VALUE (face->neighbor, r->flux[0])    += f[0];
+  GFS_VALUE (face->neighbor, r->flux[s->u]) += f[1];
+  GFS_VALUE (face->neighbor, r->flux[s->v]) += f[2];
+}
+
+static void reset_fluxes (FttCell * cell, const GfsRiver * r)
+{
+  guint v;
+  for (v = 0; v < GFS_RIVER_NVAR; v++)
+    GFS_VALUE (cell, r->flux[v]) = 0.;
+}
+
+static void sources (FttCell * cell, GfsRiver * r)
+{
+  /* metric coefficients */
+  gdouble fm[FTT_NEIGHBORS], cm;
+
+  /* Geometric source terms (see doc/figures/lonlat.tm) */
+  if (GFS_DOMAIN (r)->cell_metric) {
+    GfsDomain * domain = GFS_DOMAIN (r);
+    FttCellFace face = { cell };
+    for (face.d = 0; face.d < FTT_NEIGHBORS; face.d++)
+      fm[face.d] = (* domain->face_metric) (domain, &face);
+    gdouble dh_dl = fm[FTT_RIGHT] - fm[FTT_LEFT];
+    gdouble dh_dt = fm[FTT_TOP]   - fm[FTT_BOTTOM];
+    cm = (* domain->cell_metric) (domain, cell)*ftt_cell_size (cell);
+    gdouble dldh = cm*GFS_SIMULATION (r)->physical_params.L;
+    gdouble 
+      phiu = GFS_VALUE (cell, r->v1[1]), 
+      phiv = GFS_VALUE (cell, r->v1[2]);
+    gdouble fG = phiv*dh_dl - phiu*dh_dt;
+    gdouble g = GFS_SIMULATION (r)->physical_params.g;
+
+    gdouble etaL = GFS_VALUE (cell, r->v1[0]) - GFS_VALUE (cell, r->dv[0][0]);
+    gdouble etaR = GFS_VALUE (cell, r->v1[0]) + GFS_VALUE (cell, r->dv[0][0]);
+    GFS_VALUE (cell, r->v[1]) += r->dt*(g*(etaL*etaL + etaR*etaR)/4.*dh_dl + fG*phiv)/dldh;
+
+    etaL = GFS_VALUE (cell, r->v1[0]) - GFS_VALUE (cell, r->dv[1][0]);
+    etaR = GFS_VALUE (cell, r->v1[0]) + GFS_VALUE (cell, r->dv[1][0]);
+    GFS_VALUE (cell, r->v[2]) += r->dt*(g*(etaL*etaL + etaR*etaR)/4.*dh_dt - fG*phiu)/dldh;
+  }
+  else { /* metric unity */
+    FttDirection d;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      fm[d] = 1.;
+    cm = ftt_cell_size (cell);
+  }
+
+  /* Second-order correction for slope source term ("Sci" of Audusse
+     et al, 2004, SIAM, 25(6):2050-2065, equation 3.8) */
+  gdouble etaL = GFS_VALUE (cell, r->v1[0]) - GFS_VALUE (cell, r->dv[0][0]);
+  gdouble zbL = GFS_VALUE (cell, r->v[3]) - GFS_VALUE (cell, r->dv[0][3]);
+  gdouble etaR = GFS_VALUE (cell, r->v1[0]) + GFS_VALUE (cell, r->dv[0][0]);
+  gdouble zbR = GFS_VALUE (cell, r->v[3]) + GFS_VALUE (cell, r->dv[0][3]);
+
+  GFS_VALUE (cell, r->v[1]) += 
+    r->dt*r->g/4.*(fm[FTT_RIGHT] + fm[FTT_LEFT])*(etaL + etaR)*(zbL - zbR)/cm;
+
+  etaL = GFS_VALUE (cell, r->v1[0]) - GFS_VALUE (cell, r->dv[1][0]);
+  zbL = GFS_VALUE (cell, r->v[3]) - GFS_VALUE (cell, r->dv[1][3]);
+  etaR = GFS_VALUE (cell, r->v1[0]) + GFS_VALUE (cell, r->dv[1][0]);
+  zbR = GFS_VALUE (cell, r->v[3]) + GFS_VALUE (cell, r->dv[1][3]);
+
+  GFS_VALUE (cell, r->v[2]) += 
+    r->dt*r->g/4.*(fm[FTT_TOP] + fm[FTT_BOTTOM])*(etaL + etaR)*(zbL - zbR)/cm;
+}
+
+static void advance (GfsRiver * r, gdouble dt)
+{
+  GfsDomain * domain = GFS_DOMAIN (r);
+  guint i;
+
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) reset_fluxes, r);
+  r->dt = dt;
+  gfs_domain_face_traverse (domain, FTT_XYZ,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) face_fluxes, r);
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) sources, r);
+  for (i = 0; i < GFS_RIVER_NVAR; i++) {
+    GfsAdvectionParams par;
+    par.v = r->v[i];
+    par.fv = r->flux[i];
+    par.average = FALSE;
+    gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, &par);
+    gfs_domain_variable_centered_sources (domain, par.v, par.v, dt);
+  }
+  gfs_source_coriolis_implicit (domain, dt);
+  for (i = 0; i < GFS_RIVER_NVAR; i++)
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, r->v[i]);
+}
+
+static void copy (FttCell * cell, const GfsRiver * r)
+{
+  guint v;
+  for (v = 0; v < GFS_RIVER_NVAR; v++)
+    GFS_VALUE (cell, r->v1[v]) = GFS_VALUE (cell, r->v[v]);
+}
+
+static void cell_H (FttCell * cell,
+		    const GfsRiver * r)
+{
+  GFS_VALUE (cell, r->H) = GFS_VALUE (cell, r->zb) + GFS_VALUE (cell, r->v[0]);
+}
+
+static void cell_gradients (FttCell * cell,
+			    const GfsRiver * r)
+{
+  FttComponent c;
+  guint v;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    for (v = 0; v < GFS_RIVER_NVAR; v++)
+      GFS_VALUE (cell, r->dv[c][v]) = (* r->gradient) (cell, c, r->v[v]->i)/2.;
+    /* recontruct Zb + eta rather than Zb: see Theorem 3.1 of Audusse et al, 2004 */
+    GFS_VALUE (cell, r->dv[c][3]) = 
+      (* r->gradient) (cell, c, r->H->i)/2. - GFS_VALUE (cell, r->dv[c][0]);
+  }
+}
+
+typedef struct { 
+  FttCellTraverseFunc func;
+  FttDirection d;
+  gpointer data;
+} FaceTraverseData;
+
+static void face_traverse (FttCell * cell, FaceTraverseData * p)
+{
+  FttCell * neighbor = ftt_cell_neighbor (cell, p->d);
+  if (neighbor)
+    (* p->func) (neighbor, p->data);
+}
+
+static void domain_traverse_all_leaves (GfsDomain * domain,
+					FttCellTraverseFunc func,
+					gpointer data)
+{
+  FaceTraverseData p;
+
+  gfs_domain_traverse_leaves (domain, func, data);
+  /* now traverses boundary cells */
+  p.func = func;
+  p.data = data;
+  for (p.d = 0; p.d < FTT_NEIGHBORS; p.d++)
+    gfs_domain_cell_traverse_boundary (domain, p.d, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				       (FttCellTraverseFunc) face_traverse, &p);
+}
+
+static void river_run (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsRiver * r = GFS_RIVER (sim);
+
+  r->v[3] = r->zb = gfs_variable_from_name (domain->variables, "Zb");
+
+  r->g = sim->physical_params.g/sim->physical_params.L;
+  r->gradient = sim->advection_params.gradient;
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  gfs_simulation_set_timestep (sim);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    /* update H */
+    domain_traverse_all_leaves (domain, (FttCellTraverseFunc) cell_H, r);
+    
+    /* events */
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    /* gradients */
+    gfs_domain_timer_start (domain, "gradients");
+    gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) cell_gradients, r);
+    FttComponent c;
+    guint v;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      for (v = 0; v < GFS_RIVER_NVAR + 1; v++)
+	gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, r->dv[c][v]);
+    gfs_domain_timer_stop (domain, "gradients");
+
+    /* predictor */
+    domain_traverse_all_leaves (domain, (FttCellTraverseFunc) copy, r);
+    if (r->time_order == 2) {
+      gfs_domain_timer_start (domain, "predictor");
+      for (v = 0; v < GFS_RIVER_NVAR; v++)
+	gfs_variables_swap (r->v[v], r->v1[v]);
+      advance (r, sim->advection_params.dt/2.);
+      for (v = 0; v < GFS_RIVER_NVAR; v++)
+	gfs_variables_swap (r->v[v], r->v1[v]);
+      gfs_domain_timer_stop (domain, "predictor");
+    }
+    /* corrector */
+    gfs_domain_timer_start (domain, "corrector");
+    advance (r, sim->advection_params.dt);
+    gfs_domain_timer_stop (domain, "corrector");
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gfs_simulation_set_timestep (sim);
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+}
+
+static gdouble maximum_face_metric (FttCell * cell, GfsDomain * domain, FttComponent c)
+{
+  if (domain->face_metric) {
+    FttCellFace f;
+    f.cell = cell; f.d = 2*c;
+    gdouble fm1 = (* domain->face_metric) (domain, &f);
+    f.d = 2*c + 1;
+    gdouble fm2 = (* domain->face_metric) (domain, &f);
+    return MAX (fm1, fm2);
+  }
+  else
+    return 1.;
+}
+
+static void minimum_cfl (FttCell * cell, GfsRiver * r)
+{
+  gdouble h = GFS_VALUE (cell, r->v[0]);
+  if (h > GFS_RIVER_DRY) {
+    GfsDomain * domain = GFS_DOMAIN (r);
+    gdouble vol = ftt_cell_size (cell);
+    if (domain->cell_metric)
+      vol *= (* domain->cell_metric) (domain, cell);
+    gdouble cg = sqrt (r->g*h);
+    FttComponent c;
+    for (c = FTT_X; c <= FTT_Y; c++) {
+      gdouble uh = fabs (GFS_VALUE (cell, r->v[c + 1]));
+      gdouble fm = maximum_face_metric (cell, domain, c);
+      gdouble cfl = vol/(fm*(uh/h + cg));
+      if (cfl < r->cfl)
+	r->cfl = cfl;
+    }
+  }
+}
+
+static gdouble river_cfl (GfsSimulation * sim)
+{
+  GfsRiver * r = GFS_RIVER (sim);
+  r->cfl = G_MAXDOUBLE;
+  gfs_domain_traverse_leaves (GFS_DOMAIN (sim), (FttCellTraverseFunc) minimum_cfl, r);
+  gfs_all_reduce (GFS_DOMAIN (sim), r->cfl, MPI_DOUBLE, MPI_MIN);
+  return r->cfl;
+}
+
+static void river_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_river_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsRiver * river = GFS_RIVER (*o);
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_UINT, "time_order", TRUE},
+      {GTS_NONE}
+    };
+    var[0].data = &river->time_order;
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+  }
+}
+
+static void river_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_river_class ())->parent_class->write) (o, fp);
+
+  GfsRiver * river = GFS_RIVER (o);
+  fprintf (fp, " {\n"
+	   "  time_order = %d\n"
+	   "}",
+	   river->time_order);
+}
+
+static void river_class_init (GfsSimulationClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = river_read;
+  GTS_OBJECT_CLASS (klass)->write = river_write;
+  klass->run = river_run;
+  klass->cfl = river_cfl;
+}
+
+static gdouble cell_velocity (FttCell * cell, FttCellFace * face, GfsRiver * r)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  gdouble D = GFS_VALUE (cell, r->v[0]);
+  gdouble L = GFS_SIMULATION (r)->physical_params.L;
+  return D > GFS_RIVER_DRY ? L*gfs_vector_norm (cell, gfs_domain_velocity (GFS_DOMAIN (r)))/D : 0.;
+}
+
+static gdouble cell_velocity2 (FttCell * cell, FttCellFace * face, GfsRiver * r)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  gdouble D = GFS_VALUE (cell, r->v[0]);
+  gdouble L = GFS_SIMULATION (r)->physical_params.L;
+  return D > GFS_RIVER_DRY ? 
+    L*L*gfs_vector_norm2 (cell, gfs_domain_velocity (GFS_DOMAIN (r)))/(D*D) : 0.;
+}
+
+static void river_init (GfsRiver * r)
+{
+  GfsDomain * domain = GFS_DOMAIN (r);
+
+  gts_object_destroy (GTS_OBJECT (gfs_variable_from_name (domain->variables, "Pmac")));
+
+  r->v[0] = gfs_variable_from_name (domain->variables, "P");
+  r->v[0]->units = 1.;
+  g_free (r->v[0]->description);
+  r->v[0]->description = g_strdup ("Fluid depth");
+
+  r->v[1] = gfs_variable_from_name (domain->variables, "U");
+  r->v[1]->units = 2.;
+  g_free (r->v[1]->description);
+  r->v[1]->description = g_strdup ("x-component of the fluid flux");
+
+  r->v[2] = gfs_variable_from_name (domain->variables, "V");
+  r->v[2]->units = 2.;
+  g_free (r->v[2]->description);
+  r->v[2]->description = g_strdup ("y-component of the fluid flux");
+
+  GfsVariable * zb = gfs_domain_add_variable (domain, "Zb", "Bed elevation above datum");
+  zb->units = 1.;
+
+  r->H = gfs_domain_add_variable (domain, "H", "Elevation above datum (Zb + P)");
+  r->H->units = 1.;
+
+  r->flux[0] = gfs_domain_add_variable (domain, NULL, NULL);
+  r->flux[1] = gfs_domain_add_variable (domain, NULL, NULL);
+  r->flux[2] = gfs_domain_add_variable (domain, NULL, NULL);
+
+  r->v1[0] = gfs_domain_add_variable (domain, NULL, NULL);
+  r->v1[1] = gfs_domain_add_variable (domain, NULL, NULL);
+  r->v1[2] = gfs_domain_add_variable (domain, NULL, NULL);
+  gfs_variable_set_vector (&r->v1[1], 2);
+
+  r->dv[0][0] = gfs_domain_add_variable (domain, "Px", "x-component of the depth gradient");
+  r->dv[1][0] = gfs_domain_add_variable (domain, "Py", "y-component of the depth gradient");
+  r->dv[0][1] = gfs_domain_add_variable (domain, "Ux", "x-component of the flux gradient");
+  r->dv[1][1] = gfs_domain_add_variable (domain, "Uy", "y-component of the flux gradient");
+  r->dv[0][2] = gfs_domain_add_variable (domain, "Vx", "x-component of the flux gradient");
+  r->dv[1][2] = gfs_domain_add_variable (domain, "Vy", "y-component of the flux gradient");
+  r->dv[0][3] = gfs_domain_add_variable (domain, "Zbx", "x-component of the bed slope");
+  r->dv[1][3] = gfs_domain_add_variable (domain, "Zby", "y-component of the bed slope");
+
+  GFS_SIMULATION (r)->advection_params.gradient = gfs_center_minmod_gradient;
+  GFS_SIMULATION (r)->advection_params.cfl = 0.5;
+
+  GfsDerivedVariable * v = gfs_derived_variable_from_name (domain->derived_variables, "Velocity");
+  v->func = cell_velocity;
+  v = gfs_derived_variable_from_name (domain->derived_variables, "Velocity2");
+  v->func = cell_velocity2;
+
+  gfs_domain_remove_derived_variable (domain, "Vorticity");
+  gfs_domain_remove_derived_variable (domain, "Divergence");
+  gfs_domain_remove_derived_variable (domain, "Lambda2");
+  gfs_domain_remove_derived_variable (domain, "Curvature");
+  gfs_domain_remove_derived_variable (domain, "D2");
+
+  r->time_order = 2;
+}
+
+GfsSimulationClass * gfs_river_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_river_info = {
+      "GfsRiver",
+      sizeof (GfsRiver),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) river_class_init,
+      (GtsObjectInitFunc) river_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), 
+				  &gfs_river_info);
+  }
+
+  return klass;
+}
+
+/* GfsBcSubcritical: Object */
+
+static void subcritical (FttCellFace * f, GfsBc * b)
+{
+  gdouble hb = gfs_function_face_value (GFS_BC_VALUE (b)->val, f);
+  GfsRiver * river = GFS_RIVER (b->v->domain);
+  gdouble hi = GFS_VALUE (f->neighbor, river->v[0]);
+
+  g_assert (hi >= 0.);
+  GFS_VALUE (f->cell, b->v) = GFS_VALUE (f->neighbor, b->v) + 
+    (FTT_FACE_DIRECT (f) ? -1. : 1.)*2.*hi*(sqrt (river->g*hi) - sqrt (river->g*MAX (hb, 0.)));
+}
+
+static void bc_subcritical_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsBc * bc = GFS_BC (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_bc_subcritical_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_bc_subcritical_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (!GFS_IS_RIVER (bc->v->domain)) {
+    gts_file_error (fp, "GfsBcSubcritical only makes sense for GfsRiver simulations");
+    return;
+  }
+
+  gfs_function_set_units (GFS_BC_VALUE (bc)->val, 1.);
+}
+
+static void gfs_bc_subcritical_init (GfsBc * object)
+{
+  object->bc =  (FttFaceTraverseFunc) subcritical;
+}
+
+static void gfs_bc_subcritical_class_init (GtsObjectClass * klass)
+{
+  klass->read = bc_subcritical_read;
+}
+
+GfsBcClass * gfs_bc_subcritical_class (void)
+{
+  static GfsBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_bc_subcritical_info = {
+      "GfsBcSubcritical",
+      sizeof (GfsBcValue),
+      sizeof (GfsBcClass),
+      (GtsObjectClassInitFunc) gfs_bc_subcritical_class_init,
+      (GtsObjectInitFunc) gfs_bc_subcritical_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_bc_value_class ()),
+				  &gfs_bc_subcritical_info);
+  }
+
+  return klass;
+}
diff --git a/src/river.h b/src/river.h
new file mode 100644
index 0000000..3fc7d3d
--- /dev/null
+++ b/src/river.h
@@ -0,0 +1,68 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __RIVER_H__
+#define __RIVER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "variable.h"
+
+/* GfsRiver: Header */
+
+#define GFS_RIVER_NVAR 3
+#define GFS_RIVER_DRY 1e-6
+
+typedef struct _GfsRiver GfsRiver;
+
+struct _GfsRiver {
+  /*< private >*/
+  GfsSimulation parent;
+  gdouble cfl;
+
+  /*< public >*/
+  GfsVariable * v[GFS_RIVER_NVAR + 1], * v1[GFS_RIVER_NVAR], * zb, * H;
+  GfsVariable * dv[FTT_DIMENSION][GFS_RIVER_NVAR + 1];
+  GfsVariable * flux[GFS_RIVER_NVAR];
+  gdouble g, dt;
+  GfsCenterGradient gradient;
+  guint time_order;
+};
+
+#define GFS_RIVER(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsRiver,\
+					           gfs_river_class ())
+#define GFS_IS_RIVER(obj)         (gts_object_is_from_class (obj,\
+						   gfs_river_class ()))
+
+GfsSimulationClass * gfs_river_class        (void);
+
+/* GfsBcSubcritical: Header */
+
+#define GFS_IS_BC_SUBCRITICAL(obj)         (gts_object_is_from_class (obj,\
+						 gfs_bc_subcritical_class ()))
+GfsBcClass * gfs_bc_subcritical_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __RIVER_H__ */
diff --git a/src/simulation.c b/src/simulation.c
new file mode 100644
index 0000000..26e3c93
--- /dev/null
+++ b/src/simulation.c
@@ -0,0 +1,2021 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <gmodule.h>
+#include "config.h"
+#include "gfsconfig.h"
+#include "simulation.h"
+#include "output.h"
+#include "refine.h"
+#include "solid.h"
+#include "adaptive.h"
+#include "source.h"
+#include "vof.h"
+#include "tension.h"
+#include "map.h"
+#include "version.h"
+
+/* GfsSimulation: object */
+
+static void simulation_destroy (GtsObject * object)
+{
+  GfsSimulation * sim = GFS_SIMULATION (object);
+
+  gts_container_foreach (GTS_CONTAINER (sim->refines), (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (sim->refines));
+
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (sim->events));
+
+  gts_container_foreach (GTS_CONTAINER (sim->maps), (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (sim->maps));
+
+  gts_object_destroy (GTS_OBJECT (sim->adapts));
+  gts_object_destroy (GTS_OBJECT (sim->solids));
+
+  g_slist_foreach (sim->modules, (GFunc) g_module_close, NULL);
+  g_slist_free (sim->modules);
+  g_slist_foreach (sim->globals, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (sim->globals);
+  g_slist_foreach (sim->preloaded_modules, (GFunc) g_module_close, NULL);
+  g_slist_free (sim->preloaded_modules);
+
+  (* GTS_OBJECT_CLASS (gfs_simulation_class ())->parent_class->destroy) (object);
+}
+
+static void simulation_write (GtsObject * object, FILE * fp)
+{
+  GfsSimulation * sim = GFS_SIMULATION (object);
+  GSList * i;
+  GfsVariable * v;
+
+  (* GTS_OBJECT_CLASS (gfs_simulation_class ())->parent_class->write)
+    (object, fp);
+
+  fputs (" {\n"
+	 "  # when editing this file it is recommended to comment out the following line\n"
+	 "  GfsDeferredCompilation\n",
+	 fp);
+
+  i = sim->modules;
+  while (i) {
+    void (* module_write) (FILE *);
+    const gchar * name = NULL;
+    fprintf (fp, "  GModule %s", 
+	     g_module_symbol (i->data, "gfs_module_name", (gpointer) &name) ? name : 
+	     g_module_name (i->data));
+    if (g_module_symbol (i->data, "gfs_module_write", (gpointer) &module_write))
+      (* module_write) (fp);
+    fputc ('\n', fp);
+    i = i->next;
+  }
+
+  i = sim->globals;
+  while (i) {
+    fputs ("  ", fp);
+    (* GTS_OBJECT (i->data)->klass->write) (i->data, fp);
+    i = i->next;
+  }
+
+  fputs ("  GfsTime ", fp);
+  gfs_time_write (&sim->time, fp);
+  fputc ('\n', fp);
+
+  if (GFS_DOMAIN (sim)->max_depth_write < -1) {
+    i = sim->refines->items;
+    while (i) {
+      GtsObject * object = i->data;
+      
+      fputs ("  ", fp);
+      g_assert (object->klass->write);
+      (* object->klass->write) (object, fp);
+      fputc ('\n', fp);
+      i = i->next;
+    }
+  }
+
+  i = sim->events->items;
+  while (i) {
+    GtsObject * object = i->data;
+    GfsEvent * event = i->data;
+    
+    if (event->t < event->end && event->i < event->iend) {
+      fputs ("  ", fp);
+      g_assert (object->klass->write);
+      (* object->klass->write) (object, fp);
+      fputc ('\n', fp);
+    }
+    i = i->next;
+  }
+
+  i = GFS_DOMAIN (sim)->variables;
+  while (i) {
+    v = i->data;
+    if (v->surface_bc) {
+      fputs ("  ", fp);
+      (* GTS_OBJECT (v->surface_bc)->klass->write) (GTS_OBJECT (v->surface_bc), fp);
+      fputc ('\n', fp);
+    }
+    i = i->next;
+  }
+
+  fputs ("  GfsPhysicalParams ", fp);
+  gfs_physical_params_write (&sim->physical_params, fp);
+  fputs ("\n  GfsAdvectionParams ", fp);
+  gfs_advection_params_write (&sim->advection_params, fp);
+  fputs ("\n  GfsApproxProjectionParams ", fp);
+  gfs_multilevel_params_write (&sim->approx_projection_params, fp);
+  fputs ("\n  GfsProjectionParams ", fp);
+  gfs_multilevel_params_write (&sim->projection_params, fp);
+  fputc ('\n', fp);
+
+  i = sim->maps->items;
+  while (i) {
+    GtsObject * object = i->data;
+    g_assert (object->klass->write);
+    (* object->klass->write) (object, fp);
+    fputc ('\n', fp);
+    i = i->next;
+  }
+
+  fputc ('}', fp);
+}
+
+static gboolean strmatch (const gchar * s, const gchar * s1)
+{
+  gboolean m = !strcmp (s, s1);
+
+  if (!m) {
+    gchar * s2 = g_strconcat ("Gfs", s, NULL);
+    m = !strcmp (s2, s1);
+    g_free (s2);
+  }
+  return m;
+}
+
+static GModule * load_module (GtsFile * fp, GfsSimulation * sim)
+{
+  gts_file_next_token (fp);
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (module name)");
+    return NULL;
+  }
+  if (!g_module_supported ()) {
+    g_warning ("modules are not supported on this system");
+    gts_file_next_token (fp);
+    return NULL;
+  }
+  else {
+    GModule * module;
+
+    module = g_module_open (fp->token->str, 0);
+    if (module == NULL) {
+      gchar * name = g_strconcat (fp->token->str, 
+#if FTT_2D
+				  "2D"
+#elif FTT_2D3
+				  "2D3"
+#else
+				  "3D"
+#endif
+				  , NULL);
+      gchar * path = g_module_build_path (GFS_MODULES_DIR, name);
+      g_free (name);
+      module = g_module_open (path, 0);
+      g_free (path);
+    }
+    if (module == NULL) {
+      gts_file_error (fp, "cannot load module: %s", g_module_error ());
+      return NULL;
+    }
+    g_module_make_resident (module);
+    gts_file_next_token (fp);
+
+    void (* module_read) (GtsFile *, GfsSimulation * sim);
+    if (g_module_symbol (module, "gfs_module_read", (gpointer) &module_read)) {
+      (* module_read) (fp, sim);
+      if (fp->type == GTS_ERROR)
+	return NULL;
+    }
+    return module;
+  }
+}
+
+static void simulation_read (GtsObject ** object, GtsFile * fp)
+{
+  GfsSimulation * sim = GFS_SIMULATION (*object);
+
+  (* GTS_OBJECT_CLASS (gfs_simulation_class ())->parent_class->read) (object, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+
+    /* ------ Deferred compilation ------*/
+    if (!strcmp (fp->token->str, "GfsDeferredCompilation")) {
+      sim->deferred_compilation = TRUE;
+      gts_file_next_token (fp);
+    }
+
+    /* ------------ GModule ------------ */
+    else if (!strcmp (fp->token->str, "GModule")) {
+      GModule * module = load_module (fp, sim);
+      if (module == NULL)
+	return;
+      sim->modules = g_slist_prepend (sim->modules, module);
+    }
+
+    /* ------------ GfsTime ------------ */
+    else if (strmatch (fp->token->str, "GfsTime")) {
+      gts_file_next_token (fp);
+      gfs_time_read (&sim->time, fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+
+    /* ------------ GfsPhysicalParams ------------ */
+    else if (strmatch (fp->token->str, "GfsPhysicalParams")) {
+      gts_file_next_token (fp);
+      gfs_physical_params_read (&sim->physical_params, GFS_DOMAIN (sim), fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+
+    /* ------------ GfsProjectionParams ------------ */
+    else if (strmatch (fp->token->str, "GfsProjectionParams")) {
+      gts_file_next_token (fp);
+      gfs_multilevel_params_read (&sim->projection_params, fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+
+    /* ------------ GfsApproxProjectionParams ------------ */
+    else if (strmatch (fp->token->str, "GfsApproxProjectionParams")) {
+      gts_file_next_token (fp);
+      gfs_multilevel_params_read (&sim->approx_projection_params, fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+
+    /* ------------ GfsAdvectionParams ------------ */
+    else if (strmatch (fp->token->str, "GfsAdvectionParams")) {
+      gts_file_next_token (fp);
+      gfs_advection_params_read (&sim->advection_params, fp);
+      if (fp->type == GTS_ERROR)
+	return;
+    }
+
+    /* ------------ GtsObject ------------ */
+    else {
+      GtsObjectClass * klass = gfs_object_class_from_name (fp->token->str);
+      GtsObject * object;
+
+      if (klass == NULL) {
+	gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+	return;
+      }
+      if (gts_object_class_is_from_class (klass, gfs_box_class ())) {
+	gts_file_error (fp, "parse error (unclosed statement?)");
+	return;
+      }
+
+      object = gts_object_new (klass);
+      gfs_object_simulation_set (object, sim);
+
+      g_assert (klass->read);
+      (* klass->read) (&object, fp);
+      if (fp->type == GTS_ERROR) {
+	gts_object_destroy (object);
+	return;
+      }
+
+      if (GFS_IS_GLOBAL (object))
+	sim->globals = g_slist_append (sim->globals, object);
+      else if (GFS_IS_REFINE (object))
+	gts_container_add (GTS_CONTAINER (sim->refines), GTS_CONTAINEE (object));
+      else if (GFS_IS_ADAPT (object)) {
+	gts_container_add (GTS_CONTAINER (sim->adapts), GTS_CONTAINEE (object));
+	gts_container_add (GTS_CONTAINER (sim->events), GTS_CONTAINEE (object));
+      }
+      else if (GFS_IS_SOLID (object)) {
+	gts_container_add (GTS_CONTAINER (sim->solids), GTS_CONTAINEE (object));
+	gts_container_add (GTS_CONTAINER (sim->events), GTS_CONTAINEE (object));
+      }
+      else if (GFS_IS_EVENT (object))
+	gts_container_add (GTS_CONTAINER (sim->events), GTS_CONTAINEE (object));
+      else if (GFS_IS_MAP (object))
+	gts_container_add (GTS_CONTAINER (sim->maps), GTS_CONTAINEE (object));
+      else if (GFS_IS_SURFACE_GENERIC_BC (object))
+	;
+      else
+	g_assert_not_reached ();
+    }
+  }
+  
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+
+  sim->refines->items = g_slist_reverse (sim->refines->items);
+  sim->adapts->items = g_slist_reverse (sim->adapts->items);
+  sim->events->items = g_slist_reverse (sim->events->items);
+  sim->solids->items = g_slist_reverse (sim->solids->items);
+  sim->modules = g_slist_reverse (sim->modules);
+}
+
+/**
+ * gfs_advance_tracers:
+ * @domain: a #GfsDomain.
+ *
+ * Performs advection/difussion of tracers associated with @domain.
+ */
+void gfs_advance_tracers (GfsDomain * domain, gdouble dt)
+{
+  g_return_if_fail (domain != NULL);
+
+  GSList * i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_TRACER_VOF (i->data)) {
+      GfsVariableTracer * t = i->data;
+      
+      t->advection.dt = dt;
+      gfs_tracer_vof_advection (domain, &t->advection);
+      gfs_domain_variable_centered_sources (domain, i->data, i->data, t->advection.dt);
+    }
+    else if (GFS_IS_VARIABLE_TRACER (i->data)) {
+      GfsVariableTracer * t = i->data;
+      
+      t->advection.dt = dt;
+      gfs_tracer_advection_diffusion (domain, &t->advection);
+      gfs_domain_cell_traverse (domain,
+				FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				(FttCellTraverseFunc) GFS_VARIABLE1 (t)->fine_coarse, t);
+    }
+    i = i->next;
+  }  
+}
+
+static void simulation_run (GfsSimulation * sim)
+{
+  GfsVariable * p, * pmac, * res = NULL, * g[FTT_DIMENSION], * gmac[FTT_DIMENSION];
+  GfsVariable ** gc = sim->advection_params.gc ? g : NULL;
+  GfsDomain * domain;
+  GSList * i;
+
+  domain = GFS_DOMAIN (sim);
+
+  p = gfs_variable_from_name (domain->variables, "P");
+  g_assert (p);
+  pmac = gfs_variable_from_name (domain->variables, "Pmac");
+  g_assert (pmac);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gmac[c] = gfs_temporary_variable (domain);
+    if (sim->advection_params.gc)
+      g[c] = gfs_temporary_variable (domain);
+    else
+      g[c] = gmac[c];
+  }
+  gfs_variable_set_vector (gmac, FTT_DIMENSION);
+  gfs_variable_set_vector (g, FTT_DIMENSION);
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
+      res = i->data;
+    i = i->next;
+  }
+
+  gfs_simulation_set_timestep (sim);
+  if (sim->time.i == 0) {
+    gfs_approximate_projection (domain,
+				&sim->approx_projection_params,
+				&sim->advection_params,
+				p, sim->physical_params.alpha, res, g, NULL);
+    gfs_simulation_set_timestep (sim);
+    gfs_advance_tracers (domain, sim->advection_params.dt/2.);
+  }
+  else if (sim->advection_params.gc)
+    gfs_update_gradients (domain, p, sim->physical_params.alpha, g);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    gfs_predicted_face_velocities (domain, FTT_DIMENSION, &sim->advection_params);
+    
+    gfs_variables_swap (p, pmac);
+    gfs_mac_projection (domain,
+    			&sim->projection_params, 
+    			&sim->advection_params,
+			p, sim->physical_params.alpha, gmac, NULL);
+    gfs_variables_swap (p, pmac);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
+
+    gfs_centered_velocity_advection_diffusion (domain,
+					       FTT_DIMENSION,
+					       &sim->advection_params,
+					       gmac,
+					       sim->time.i > 0 || !gc ? gc : gmac,
+					       sim->physical_params.alpha);
+    if (gc) {
+      gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, sim->time.i > 0 ? gc : gmac, 
+				       -sim->advection_params.dt);
+    }
+    else if (gfs_has_source_coriolis (domain)) {
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, sim->advection_params.dt);
+      gfs_source_coriolis_implicit (domain, sim->advection_params.dt);
+      gfs_correct_centered_velocities (domain, FTT_DIMENSION, gmac, -sim->advection_params.dt);
+    }
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    gfs_approximate_projection (domain,
+   				&sim->approx_projection_params, 
+    				&sim->advection_params, 
+				p, sim->physical_params.alpha, res, g, NULL);
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gfs_simulation_set_timestep (sim);
+    gfs_advance_tracers (domain, sim->advection_params.dt);
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gts_object_destroy (GTS_OBJECT (gmac[c]));
+    if (sim->advection_params.gc)
+      gts_object_destroy (GTS_OBJECT (g[c]));
+  }
+}
+
+static gdouble simulation_cfl (GfsSimulation * sim)
+{
+  return gfs_domain_cfl (GFS_DOMAIN (sim), FTT_TRAVERSE_LEAFS, -1);
+}
+
+static void gfs_simulation_class_init (GfsSimulationClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->write =   simulation_write;
+  GTS_OBJECT_CLASS (klass)->read =    simulation_read;
+  GTS_OBJECT_CLASS (klass)->destroy = simulation_destroy;
+
+  klass->run = simulation_run;
+  klass->cfl = simulation_cfl;
+}
+
+/* Derived variables */
+
+static gdouble cell_x (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    gfs_face_ca (face, &p);
+  else
+    gfs_cell_cm (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.x;
+}
+
+static gdouble cell_y (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    gfs_face_ca (face, &p);
+  else
+    gfs_cell_cm (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.y;
+}
+
+static gdouble cell_z (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    gfs_face_ca (face, &p);
+  else
+    gfs_cell_cm (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.z;
+}
+
+static gdouble cell_ax (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  if (!GFS_IS_MIXED (cell))
+    return 0.;
+  else {
+    FttVector p = GFS_STATE (cell)->solid->ca;
+    gfs_simulation_map_inverse (sim, &p);
+    return p.x;
+  }
+}
+
+static gdouble cell_ay (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  if (!GFS_IS_MIXED (cell))
+    return 0.;
+  else {
+    FttVector p = GFS_STATE (cell)->solid->ca;
+    gfs_simulation_map_inverse (sim, &p);
+    return p.y;
+  }
+}
+
+static gdouble cell_az (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  if (!GFS_IS_MIXED (cell))
+    return 0.;
+  else {
+    FttVector p = GFS_STATE (cell)->solid->ca;
+    gfs_simulation_map_inverse (sim, &p);
+    return p.z;
+  }
+}
+
+static gdouble cell_cx (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.x;
+}
+
+static gdouble cell_cy (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.y;
+}
+
+static gdouble cell_cz (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  gfs_simulation_map_inverse (sim, &p);
+  return p.z;
+}
+
+static gdouble cell_rx (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  return p.x;
+}
+
+static gdouble cell_ry (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  return p.y;
+}
+
+static gdouble cell_rz (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  FttVector p;
+
+  g_return_val_if_fail (cell != NULL || face != NULL, 0.);
+
+  if (face)
+    ftt_face_pos (face, &p);
+  else
+    ftt_cell_pos (cell, &p);
+  return p.z;
+}
+
+static gdouble cell_dV (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  gdouble dV = ftt_cell_volume (cell);
+  gdouble L = sim->physical_params.L;
+#if FTT_2D
+  dV *= L*L;
+#else
+  dV *= L*L*L;
+#endif
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a*dV : dV;
+}
+
+static gdouble cell_dL (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  gdouble dL = ftt_cell_size (cell);
+  gdouble L = sim->physical_params.L;
+  return L*dL;
+}
+
+static gdouble cell_t (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  return sim->time.t;
+}
+
+static gdouble cell_dt (FttCell * cell, FttCellFace * face, GfsSimulation * sim)
+{
+  return sim->advection_params.dt;
+}
+
+static gdouble cell_vorticity (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return gfs_vorticity (cell, gfs_domain_velocity (domain));
+}
+
+static gdouble cell_divergence (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return gfs_divergence (cell, gfs_domain_velocity (domain));
+}
+
+static gdouble cell_velocity_norm (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  gdouble L = GFS_SIMULATION (domain)->physical_params.L;
+  return L*gfs_vector_norm (cell, gfs_domain_velocity (domain));
+}
+
+static gdouble cell_velocity_norm2 (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  gdouble L = GFS_SIMULATION (domain)->physical_params.L;
+  return L*L*gfs_vector_norm2 (cell, gfs_domain_velocity (domain));
+}
+
+static gdouble cell_level (FttCell * cell)
+{
+  return ftt_cell_level (cell);
+}
+
+static gdouble cell_fraction (FttCell * cell)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+}
+
+static gdouble cell_solid_area (FttCell * cell)
+{
+  FttVector n;
+  gfs_solid_normal (cell, &n);
+  return ftt_vector_norm (&n);
+}
+
+static gdouble cell_solid_sr (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_RIGHT] : 1.;
+}
+
+static gdouble cell_solid_sl (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_LEFT] : 1.;
+}
+
+static gdouble cell_solid_st (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_TOP] : 1.;
+}
+
+static gdouble cell_solid_sb (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_BOTTOM] : 1.;
+}
+
+#if !FTT_2D
+static gdouble cell_solid_sf (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_FRONT] : 1.;
+}
+
+static gdouble cell_solid_sk (FttCell * cell)
+{
+  return GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->s[FTT_BACK] : 1.;
+}
+#endif /* 3D */
+
+static gdouble cell_velocity_lambda2 (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return gfs_vector_lambda2 (cell, gfs_domain_velocity (domain));
+}
+
+static gdouble cell_streamline_curvature (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  gdouble L = GFS_SIMULATION (domain)->physical_params.L;
+  return gfs_streamline_curvature (cell, gfs_domain_velocity (domain))/L;
+}
+
+static gdouble cell_2nd_principal_invariant (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return gfs_2nd_principal_invariant (cell, gfs_domain_velocity (domain))/ftt_cell_size (cell);
+}
+
+static gdouble cell_pid (FttCell * cell)
+{
+  while (!FTT_CELL_IS_ROOT (cell))
+    cell = ftt_cell_parent (cell);
+  return GFS_BOX (FTT_ROOT_CELL (cell)->parent)->pid;
+}
+
+static gdouble cell_id (FttCell * cell)
+{
+  while (!FTT_CELL_IS_ROOT (cell))
+    cell = ftt_cell_parent (cell);
+  return GFS_BOX (FTT_ROOT_CELL (cell)->parent)->id;
+}
+
+static void simulation_init (GfsSimulation * object)
+{
+  GfsDomain * domain = GFS_DOMAIN (object);
+  /* Please update http://gfs.sourceforge.net/wiki/index.php/Domain_variables 
+     when changing this list */
+  static GfsDerivedVariableInfo derived_variable[] = {
+    { "x", "x-coordinate of the center of mass of the cell", cell_x },
+    { "y", "y-coordinate of the center of mass of the cell", cell_y },
+    { "z", "z-coordinate of the center of mass of the cell", cell_z },
+    { "ax", "x-coordinate of the center of area of the solid surface", cell_ax },
+    { "ay", "y-coordinate of the center of area of the solid surface", cell_ay },
+    { "az", "z-coordinate of the center of area of the solid surface", cell_az },
+    { "cx", "x-coordinate of the center of the cell", cell_cx },
+    { "cy", "y-coordinate of the center of the cell", cell_cy },
+    { "cz", "z-coordinate of the center of the cell", cell_cz },
+    { "rx", "x-coordinate of the center of the cell (internal)", cell_rx },
+    { "ry", "y-coordinate of the center of the cell (internal)", cell_ry },
+    { "rz", "z-coordinate of the center of the cell (internal)", cell_rz },
+    { "dV", "volume of the cell", cell_dV},
+    { "dL", "length of the cell", cell_dL},
+    { "t",  "Physical time", cell_t },
+    { "dt", "Timestep", cell_dt },
+    { "Vorticity", "Norm of the vorticity vector of the velocity field", cell_vorticity },
+    { "Divergence", "Divergence of the velocity field", cell_divergence },
+    { "Velocity", "Norm of the velocity vector", cell_velocity_norm },
+    { "Velocity2", "Squared norm of the velocity vector", cell_velocity_norm2 },
+    { "Level", "Quad/octree level of the cell", cell_level },
+    { "A", "Fluid fraction of the cell", cell_fraction },
+    { "S", "Area of the solid contained in the cell", cell_solid_area },
+    { "Sr", "Fluid fraction of the right cell face", cell_solid_sr },
+    { "Sl", "Fluid fraction of the left cell face", cell_solid_sl },
+    { "St", "Fluid fraction of the top cell face", cell_solid_st },
+    { "Sb", "Fluid fraction of the bottom cell face", cell_solid_sb },
+#if !FTT_2D
+    { "Sf", "Fluid fraction of the front cell face", cell_solid_sf },
+    { "Sk", "Fluid fraction of the back cell face", cell_solid_sk },    
+#endif /* 3D */
+    { "Lambda2", "Vortex-detection criterion of Jeong & Hussein", cell_velocity_lambda2 },
+    { "Curvature",  "Curvature of the local streamline", cell_streamline_curvature },
+    { "D2", "Second principal invariant of the deformation tensor", cell_2nd_principal_invariant },
+    { "Pid", "Parent box process ID", cell_pid },
+    { "Id", "Parent box ID", cell_id },
+    { NULL, NULL, NULL}
+  };
+
+  GfsVariable * v;
+  v = gfs_domain_add_variable (domain, "P",    "Approximate projection pressure");
+  v->centered = TRUE;
+  v->units = 2.;
+  v = gfs_domain_add_variable (domain, "Pmac", "MAC projection pressure");
+  v->centered = TRUE;  
+  v->units = 2.;
+  GfsVariable * u[FTT_DIMENSION];
+  u[0] = gfs_domain_add_variable (domain, "U",    "x-component of the velocity");
+  u[0]->units = 1.;
+  u[1] = gfs_domain_add_variable (domain, "V",    "y-component of the velocity");
+  u[1]->units = 1.;
+#if (!FTT_2D)
+  u[2] = gfs_domain_add_variable (domain, "W",    "z-component of the velocity");
+  u[2]->units = 1.;
+#endif /* FTT_3D */
+  gfs_variable_set_vector (u, FTT_DIMENSION);
+
+  GfsDerivedVariableInfo * dv = derived_variable;
+  while (dv->name) {
+    g_assert (gfs_domain_add_derived_variable (domain, *dv));
+    dv++;
+  }
+  domain->derived_variables = g_slist_reverse (domain->derived_variables);
+
+  gfs_time_init (&object->time);
+  gfs_physical_params_init (&object->physical_params);
+
+  gfs_advection_params_init (&object->advection_params);
+  object->advection_params.flux = gfs_face_velocity_advection_flux;
+  object->advection_params.average = TRUE;
+
+  gfs_multilevel_params_init (&object->projection_params);
+  gfs_multilevel_params_init (&object->approx_projection_params);
+
+  object->solids = GTS_SLIST_CONTAINER (gts_container_new
+					(GTS_CONTAINER_CLASS
+					 (gts_slist_container_class ())));
+  object->output_solid = TRUE;
+
+  object->refines = GTS_SLIST_CONTAINER (gts_container_new
+					 (GTS_CONTAINER_CLASS
+					  (gts_slist_container_class ())));
+  object->maps = GTS_SLIST_CONTAINER (gts_container_new
+				      (GTS_CONTAINER_CLASS
+				       (gts_slist_container_class ())));
+  object->adapts = GTS_SLIST_CONTAINER (gts_container_new
+					(GTS_CONTAINER_CLASS
+					 (gts_slist_container_class ())));
+  gfs_adapt_stats_init (&object->adapts_stats);
+  object->events = GTS_SLIST_CONTAINER (gts_container_new
+					(GTS_CONTAINER_CLASS
+					 (gts_slist_container_class ())));
+  object->modules = object->preloaded_modules = NULL;
+
+  object->deferred_compilation = FALSE;
+  
+  object->tnext = 0.;
+}
+
+GfsSimulationClass * gfs_simulation_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_simulation_info = {
+      "GfsSimulation",
+      sizeof (GfsSimulation),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) gfs_simulation_class_init,
+      (GtsObjectInitFunc) simulation_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_domain_class ()),
+				  &gfs_simulation_info);
+  }
+
+  return klass;
+}
+
+GfsSimulation * gfs_simulation_new (GfsSimulationClass * klass)
+{
+  GfsSimulation * object;
+
+  object = GFS_SIMULATION (gts_graph_new (GTS_GRAPH_CLASS (klass),
+					  GTS_GNODE_CLASS (gfs_box_class ()),
+					  GTS_GEDGE_CLASS (gfs_gedge_class ())));
+
+  return object;
+}
+
+static void init_non_variable (GfsEvent * event, GfsSimulation * sim)
+{
+  if (!GFS_IS_VARIABLE (event))
+    gfs_event_init (event, sim);
+}
+
+/**
+ * gfs_simulation_init:
+ * @sim: a #GfsSimulation.
+ *
+ * Initialises @sim: matches boundary conditions, applies boundary
+ * conditions and initialises all variables, etc...
+ */
+void gfs_simulation_init (GfsSimulation * sim)
+{
+  g_return_if_fail (sim != NULL);
+
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) init_non_variable, sim);
+
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  gfs_domain_match (domain);
+  gfs_set_merged (domain);
+  GSList * i = domain->variables;
+  while (i) {
+    gfs_event_init (GFS_EVENT (i->data), sim);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, i->data);
+    i = i->next;
+  }
+  gfs_domain_cell_traverse (domain,
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+}
+
+static void refine_cell_corner (FttCell * cell, GfsDomain * domain)
+{
+  if (ftt_refine_corner (cell))
+    ftt_cell_refine_single (cell, domain->cell_init, domain->cell_init_data);
+}
+
+static void check_face (FttCellFace * f, guint * nf)
+{
+  GfsSolidVector * s = GFS_STATE (f->cell)->solid;
+
+  if (s && !f->neighbor && s->s[f->d] > 0. && s->s[f->d] < 1.)
+    (*nf)++;
+}
+
+static void check_solid_fractions (GfsBox * box, guint * nf)
+{
+  FttDirection d;
+
+  gfs_cell_check_solid_fractions (box->root);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    ftt_face_traverse_boundary (box->root, d, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttFaceTraverseFunc) check_face, nf);
+}
+
+static void is_diffusion (GfsSource * s, gboolean * diffusion)
+{
+  *diffusion = (GFS_IS_SOURCE_DIFFUSION (s) != NULL);
+}
+
+static void set_permanent (FttCell * cell)
+{
+  cell->flags |= GFS_FLAG_PERMANENT;
+}
+
+/**
+ * gfs_simulation_get_solids:
+ * @sim: a #GfsSimulation.
+ *
+ * Returns: a new list of #GfsSolid defining the solid boundaries
+ * contained in @sim.
+ */
+GSList * gfs_simulation_get_solids (GfsSimulation * sim)
+{
+  g_return_val_if_fail (sim != NULL, NULL);
+
+  GSList * solids = NULL, * i = sim->solids->items;
+  while (i) {
+    solids = g_slist_prepend (solids, i->data);
+    i = i->next;
+  }
+  return solids;
+}
+
+/**
+ * gfs_simulation_refine:
+ * @sim: a #GfsSimulation.
+ *
+ * Calls the @refine() methods of the #GfsRefine of @sim. Initialize the
+ * solid fractions by calling gfs_init_solid_fractions(). Matches the
+ * boundaries by calling gfs_domain_match().
+ */
+void gfs_simulation_refine (GfsSimulation * sim)
+{
+  GSList * i;
+  guint depth, nf = 0;
+  gint l;
+  GfsDomain * domain;
+
+  g_return_if_fail (sim != NULL);
+
+  domain = GFS_DOMAIN (sim);
+
+  gfs_domain_timer_start (domain, "simulation_refine");
+  i = sim->refines->items;
+  while (i) {
+    GfsRefine * refine = i->data;
+    GSList * next = i->next;
+    
+    g_assert (GFS_REFINE_CLASS (GTS_OBJECT (refine)->klass)->refine);
+    (* GFS_REFINE_CLASS (GTS_OBJECT (refine)->klass)->refine) (refine, sim);
+    i = next;
+  }
+
+  depth = gfs_domain_depth (domain);
+  for (l = depth - 2; l >= 0; l--)
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+			      (FttCellTraverseFunc) refine_cell_corner, 
+			      domain);
+
+  gfs_domain_match (domain);
+  gfs_domain_timer_stop (domain, "simulation_refine");
+
+  GSList * solids = gfs_simulation_get_solids (sim);
+  if (solids) {
+    gfs_domain_timer_start (domain, "solid_fractions");
+    sim->thin = gfs_domain_init_solid_fractions (domain, solids, TRUE,
+						 (FttCellCleanupFunc) gfs_cell_cleanup, domain,  
+						 NULL);
+    g_slist_free (solids);
+    gfs_domain_match (domain);
+    gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			       (FttCellTraverseFunc) set_permanent, NULL);
+    gfs_domain_timer_stop (domain, "solid_fractions");
+  }
+  gts_container_foreach (GTS_CONTAINER (sim), (GtsFunc) check_solid_fractions, &nf);
+  if (nf > 0) {
+    GSList * i = domain->variables;
+    gboolean diffusion = FALSE;
+    
+    while (i && !diffusion) {
+      GfsVariable * v = i->data;
+
+      if (v->sources)
+	gts_container_foreach (v->sources, (GtsFunc) is_diffusion, &diffusion);
+      i = i->next;
+    }
+    if (diffusion)
+      g_warning ("the solid surface cuts %d boundary cells,\n"
+		 "this may cause errors for diffusion terms\n", nf);
+  }
+}
+
+/**
+ * gfs_simulation_read:
+ * @fp: a #GtsFile.
+ *
+ * Reads a simulation file from @fp.
+ *
+ * Returns: the #GfsSimulation or %NULL if an error occured, in which
+ * case the @pos and @error fields of @fp are set.
+ */
+GfsSimulation * gfs_simulation_read (GtsFile * fp)
+{
+  GfsDomain * d;
+  GSList * ml = NULL; /* list of preloaded modules */
+
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  while (fp->type == '\n')
+     gts_file_next_token (fp);
+
+  while (fp->type == GTS_STRING)
+    if (!strcmp (fp->token->str, "GModule")) { /* preloaded module */
+      GModule * module = load_module (fp, NULL);
+      if (module == NULL)
+	return NULL;
+      ml = g_slist_prepend (ml, module);
+    }
+    else {
+      gts_file_error (fp, "unknown keyword `%s'", fp->token->str);
+      return NULL;
+    }
+
+  while (fp->type == '\n')
+     gts_file_next_token (fp);
+      
+  d = gfs_domain_read (fp);
+  if (d != NULL && !GFS_IS_SIMULATION (d)) {
+    gts_file_error (fp, "parent graph is not a GfsSimulation");
+    gts_object_destroy (GTS_OBJECT (d));
+    g_slist_free (ml);
+    return NULL;
+  }
+  if (d)
+    GFS_SIMULATION (d)->preloaded_modules = g_slist_reverse (ml);
+  else
+    g_slist_free (ml);
+  return GFS_SIMULATION (d);
+}
+
+/**
+ * gfs_simulation_write:
+ * @sim: a #GfsSimulation.
+ * @max_depth: the maximum depth at which to stop writing cell tree
+ * data (-1 means no limit).
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a text representation of @sim. If @max_depth is
+ * smaller or equal to -2, no cell tree data is written.  
+ */
+void gfs_simulation_write (GfsSimulation * sim,
+			   gint max_depth,		  
+			   FILE * fp)
+{
+  gint depth;
+  GfsDomain * domain;
+
+  g_return_if_fail (sim != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "# Gerris Flow Solver %dD version %s (%s)\n",
+	   FTT_DIMENSION, GFS_VERSION, GFS_BUILD_VERSION);
+  GSList * i = sim->preloaded_modules;
+  while (i) {
+    void (* module_write) (FILE *);
+    const gchar * name = NULL;
+    fprintf (fp, "GModule %s", 
+	     g_module_symbol (i->data, "gfs_module_name", (gpointer) &name) ? name : 
+	     g_module_name (i->data));
+    if (g_module_symbol (i->data, "gfs_module_write", (gpointer) &module_write))
+      (* module_write) (fp);
+    fputc ('\n', fp);
+    i = i->next;
+  }
+  domain = GFS_DOMAIN (sim);
+  depth = domain->max_depth_write;
+  domain->max_depth_write = max_depth;
+  gts_graph_write (GTS_GRAPH (sim), fp);
+  domain->max_depth_write = depth;
+}
+
+#ifdef HAVE_MPI
+static void count_edges (GtsGEdge * e, guint * nedge)
+{
+  (*nedge)++;
+}
+
+static void write_node (GtsObject * node, gpointer * data)
+{
+  FILE * fp = data[0];
+  guint * nnode = data[1];
+
+  node->reserved = GUINT_TO_POINTER ((*nnode)++);
+  if (node->klass->write)
+    (* node->klass->write) (node, fp);
+  fputc ('\n', fp);
+}
+
+static void write_edge (GtsGEdge * edge, FILE * fp)
+{
+  fprintf (fp, "%u %u", 
+	   GPOINTER_TO_UINT (GTS_OBJECT (edge->n1)->reserved),
+	   GPOINTER_TO_UINT (GTS_OBJECT (edge->n2)->reserved));
+  if (GTS_OBJECT (edge)->klass->write)
+    (* GTS_OBJECT (edge)->klass->write) (GTS_OBJECT (edge), fp);
+  fputc ('\n', fp);
+}
+#endif /* HAVE_MPI */
+
+/**
+ * gfs_simulation_union_write:
+ * @sim: a #GfsSimulation.
+ * @max_depth: the maximum depth at which to stop writing cell tree
+ * data (-1 means no limit).
+ * @fp: a file pointer.
+ *
+ * Identical to gfs_simulation_write() for serial simulations. For
+ * parallel simulations writes the union of the simulations on all
+ * processes to @fp.
+ */
+void gfs_simulation_union_write (GfsSimulation * sim,
+				 gint max_depth,		  
+				 FILE * fp)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+
+  g_return_if_fail (sim != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (domain->pid < 0)
+    gfs_simulation_write (sim, max_depth, fp);
+  else {
+#ifdef HAVE_MPI
+    int gsize;
+    guint * nbox;
+
+    MPI_Comm_size (MPI_COMM_WORLD, &gsize);
+    nbox = g_malloc (sizeof (guint)*gsize);
+    nbox[domain->pid] = gts_container_size (GTS_CONTAINER (sim));
+    MPI_Allgather (&nbox[domain->pid], 1, MPI_UNSIGNED, nbox, 1, MPI_UNSIGNED, MPI_COMM_WORLD);
+    /* nbox[] now contains the number of boxes on each PE */
+
+    /* see gts/src/graph.c:gts_graph_write() for the original (serial) implementation */
+    GtsGraph * g = GTS_GRAPH (sim);
+    guint nedge = 0;
+    gts_graph_foreach_edge (g, (GtsFunc) count_edges, &nedge);
+    gfs_all_reduce (domain, nedge, MPI_UNSIGNED, MPI_SUM);
+
+    if (domain->pid == 0) {
+      fprintf (fp, "# Gerris Flow Solver %dD version %s (%s)\n",
+	       FTT_DIMENSION, GFS_VERSION, GFS_BUILD_VERSION);
+      guint i, nboxes = 0;
+      for (i = 0; i < gsize; i++)
+	nboxes += nbox[i];
+      fprintf (fp, "%u %u", nboxes, nedge);
+      if (GTS_OBJECT (g)->klass->write)
+	(* GTS_OBJECT (g)->klass->write) (GTS_OBJECT (g), fp);
+      fputc ('\n', fp);
+    }
+
+    gint depth = domain->max_depth_write;
+    guint i, nnode = 1;
+    gpointer data[2];
+
+    for (i = 0; i < domain->pid; i++)
+      nnode += nbox[i];
+    g_free (nbox);
+
+    FILE * fpp = gfs_union_open (fp, domain->pid);
+    data[0] = fpp;
+    data[1] = &nnode;
+    domain->max_depth_write = max_depth;
+    gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) write_node, data);
+    domain->max_depth_write = depth;
+    gfs_union_close (fp, domain->pid, fpp);
+
+    fpp = gfs_union_open (fp, domain->pid);
+    gts_graph_foreach_edge (g, (GtsFunc) write_edge, fpp);
+    gfs_union_close (fp, domain->pid, fpp);
+
+    gts_container_foreach (GTS_CONTAINER (g), (GtsFunc) gts_object_reset_reserved, NULL);
+#endif /* HAVE_MPI */
+  }
+}
+
+static gdouble min_cfl (GfsSimulation * sim)
+{
+  gdouble cfl = (sim->advection_params.scheme == GFS_NONE ?
+		 G_MAXDOUBLE :
+		 sim->advection_params.cfl);
+  GSList * i = GFS_DOMAIN (sim)->variables;
+  
+  while (i) {
+    GfsVariable * v = i->data;
+
+    if (GFS_IS_VARIABLE_TRACER (v) && 
+	GFS_VARIABLE_TRACER (v)->advection.scheme != GFS_NONE &&
+	GFS_VARIABLE_TRACER (v)->advection.cfl < cfl)
+      cfl = GFS_VARIABLE_TRACER (v)->advection.cfl;
+    i = i->next;
+  }
+
+  return cfl;
+}
+
+/**
+ * gfs_simulation_set_timestep:
+ * @sim: a #GfsSimulation.
+ *
+ * Sets the time step for the next iteration of @sim using the CFL
+ * (computed using gfs_domain_cfl()), the stability conditions for
+ * source terms and taking into account the timings of the various
+ * #GfsEvent associated to @sim.
+ *
+ * More precisely, the time step is adjusted (if necessary) so that
+ * the time of the closest event is exactly reached after the
+ * iteration.  
+ */
+void gfs_simulation_set_timestep (GfsSimulation * sim)
+{
+  gdouble t, cfl;
+
+  g_return_if_fail (sim != NULL);
+
+  t = sim->time.t;
+  if ((cfl = min_cfl (sim)) < G_MAXDOUBLE)
+    sim->advection_params.dt = cfl*(* GFS_SIMULATION_CLASS (GTS_OBJECT (sim)->klass)->cfl) (sim);
+  else
+    sim->advection_params.dt = G_MAXINT;
+  if (sim->advection_params.dt > sim->time.dtmax)
+    sim->advection_params.dt = sim->time.dtmax;
+
+  GSList *  i = GFS_DOMAIN (sim)->variables;
+  while (i) {
+    GfsVariable * v = i->data;
+    if (v->sources) {
+      GSList * j = GTS_SLIST_CONTAINER (v->sources)->items;
+      while (j) {
+	GfsSourceGeneric * s = j->data;
+	if (GFS_SOURCE_GENERIC_CLASS (GTS_OBJECT (s)->klass)->stability) {
+	  gdouble dt = (* GFS_SOURCE_GENERIC_CLASS (GTS_OBJECT (s)->klass)->stability) (s, sim);
+	  if (dt < sim->advection_params.dt)
+	    sim->advection_params.dt = dt;
+	}
+	j = j->next;
+      }
+    }
+    i = i->next;
+  }
+
+  gfs_all_reduce (GFS_DOMAIN (sim), sim->advection_params.dt, MPI_DOUBLE, MPI_MIN);
+
+  gdouble tnext = G_MAXINT;
+  i = sim->events->items;
+  while (i) {
+    gdouble next = gfs_event_next (i->data, sim);
+    if (t < next && next < tnext)
+      tnext = next + 1e-9;
+    i = i->next;
+  }
+  if (sim->time.end < tnext)
+    tnext = sim->time.end;
+
+  gdouble n = ceil ((tnext - t)/sim->advection_params.dt);
+  if (n > 0. && n < G_MAXINT) {
+    sim->advection_params.dt = (tnext - t)/n;
+    if (n == 1.)
+      sim->tnext = tnext;
+    else
+      sim->tnext = t + sim->advection_params.dt;
+  }
+  else
+    sim->tnext = t + sim->advection_params.dt;
+
+  if (sim->advection_params.dt < 1e-9)
+    sim->advection_params.dt = 1e-9;
+}
+
+/**
+ * gfs_time_write:
+ * @t: the time structure.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a text representation of the time structure @t.
+ */
+void gfs_time_write (GfsTime * t, FILE * fp)
+{
+  g_return_if_fail (t != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "{ i = %u t = %g ", t->i, t->t);
+  if (t->start != 0.)
+    fprintf (fp, "start = %g ", t->start);
+  if (t->istart != 0)
+    fprintf (fp, "start = %u ", t->istart);
+  if (t->end < G_MAXDOUBLE)
+    fprintf (fp, "end = %g ", t->end);
+  if (t->iend < G_MAXINT)
+    fprintf (fp, "iend = %u ", t->iend);
+  if (t->dtmax < G_MAXDOUBLE)
+    fprintf (fp, "dtmax = %g ", t->dtmax);
+  fputc ('}', fp);
+}
+
+/**
+ * gfs_time_init:
+ * @t: the #GfsTime.
+ *
+ * Initializes the time structure @t with default values.
+ */
+void gfs_time_init (GfsTime * t)
+{
+  g_return_if_fail (t != NULL);
+  
+  t->t = t->start = 0.;
+  t->end = G_MAXDOUBLE;
+
+  t->i = t->istart = 0;
+  t->iend = G_MAXINT;
+
+  t->dtmax = G_MAXDOUBLE;
+}
+
+/**
+ * gfs_time_read:
+ * @t: the #GfsTime.
+ * @fp: the #GtsFile.
+ *
+ * Reads a time structure from @fp and puts it in @t.
+ */
+void gfs_time_read (GfsTime * t, GtsFile * fp)
+{
+  GtsFileVariable var[] = {
+    {GTS_DOUBLE, "t",      TRUE},
+    {GTS_DOUBLE, "start",  TRUE},
+    {GTS_DOUBLE, "end",    TRUE},
+    {GTS_UINT,   "i",      TRUE},
+    {GTS_UINT,   "istart", TRUE},
+    {GTS_UINT,   "iend",   TRUE},
+    {GTS_DOUBLE, "dtmax",  TRUE},
+    {GTS_NONE}
+  };
+
+  g_return_if_fail (t != NULL);
+  g_return_if_fail (fp != NULL);
+
+  var[0].data = &t->t;
+  var[1].data = &t->start;
+  var[2].data = &t->end;
+  var[3].data = &t->i;
+  var[4].data = &t->istart;
+  var[5].data = &t->iend;
+  var[6].data = &t->dtmax;
+
+  gts_file_assign_variables (fp, var);
+
+  if (t->t < t->start)
+    t->t = t->start;
+  if (t->i < t->istart)
+    t->i = t->istart;
+}
+
+/**
+ * gfs_physical_params_write:
+ * @p: the physical parameters structure.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a text representation of the physical parameters
+ * structure @p.  
+ */
+void gfs_physical_params_write (GfsPhysicalParams * p, FILE * fp)
+{
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (fp != NULL);
+
+  fprintf (fp, "{ g = %g L = %g", p->g, p->L);
+  if (p->alpha) {
+    fputs (" alpha =", fp);
+    gfs_function_write (p->alpha, fp);
+  }
+  fputs (" }", fp);
+}
+
+/**
+ * gfs_physical_params_init:
+ * @p: the #GfsPhysicalParams.
+ *
+ * Initializes the physical parameters structure @p with default values.
+ */
+void gfs_physical_params_init (GfsPhysicalParams * p)
+{
+  g_return_if_fail (p != NULL);
+  
+  p->g = p->L = 1.;
+  p->alpha = NULL;
+}
+
+/**
+ * gfs_physical_params_read:
+ * @p: the #GfsPhysicalParams.
+ * @domain: a #GfsDomain.
+ * @fp: the #GtsFile.
+ *
+ * Reads a physical parameters structure from @fp and puts it in @p.
+ */
+void gfs_physical_params_read (GfsPhysicalParams * p, GfsDomain * domain, GtsFile * fp)
+{
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return;
+  }
+  fp->scope_max++;
+  gts_file_next_token (fp);
+  while (fp->type != GTS_ERROR && fp->type != '}') {
+    if (fp->type == '\n') {
+      gts_file_next_token (fp);
+      continue;
+    }
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a keyword");
+      return;
+    }
+    else {
+      gchar * id = g_strdup (fp->token->str);
+
+      gts_file_next_token (fp);
+      if (fp->type != '=') {
+	gts_file_error (fp, "expecting `='");
+	return;
+      }
+      gts_file_next_token (fp);
+
+      if (!strcmp (id, "g")) {
+	/* fixme: units? */
+	p->g = gfs_read_constant (fp, domain);
+	if (fp->type == GTS_ERROR) {
+	  g_free (id);
+	  return;
+	}
+      }
+      else if (!strcmp (id, "L")) {
+	p->L = gfs_read_constant (fp, domain);
+	if (fp->type == GTS_ERROR) {
+	  g_free (id);
+	  return;
+	}
+	if (p->L == 0.) {
+	  g_free (id);
+	  gts_file_error (fp, "L must be different from zero");
+	  return;
+	}
+      }
+      else if (!strcmp (id, "alpha")) {
+	p->alpha = gfs_function_new (gfs_function_class (), 0.);
+	gfs_function_read (p->alpha, domain, fp);
+	if (fp->type == GTS_ERROR) {
+	  g_free (id);
+	  gts_object_destroy (GTS_OBJECT (p->alpha));
+	  return;
+	}
+      }
+      else {
+	g_free (id);
+	gts_file_error (fp, "unknown keyword `%s'", id);
+	return;
+      }
+      g_free (id);
+    }
+  }
+  if (fp->type != '}') {
+    gts_file_error (fp, "expecting a closing brace");
+    return;
+  }
+  fp->scope_max--;
+  gts_file_next_token (fp);
+}
+
+static void error_handler (const gchar *log_domain,
+			   GLogLevelFlags log_level,
+			   const gchar *message,
+			   gpointer user_data)
+{
+  GfsDomain * domain = user_data;
+  g_slist_free (domain->variables_io);
+  domain->variables_io = NULL;
+  GSList * i = domain->variables;
+  while (i) {
+    if (GFS_VARIABLE1 (i->data)->name)
+      domain->variables_io = g_slist_append (domain->variables_io, i->data);
+    i = i->next;
+  }
+  gchar fname[20] = "error.gfs";
+  if (domain->pid >= 0)
+    snprintf (fname, 20, "error-%d.gfs", domain->pid);
+  FILE * fp = fopen (fname, "w");
+  if (fp) {
+    gfs_simulation_write (GFS_SIMULATION (domain), -1, fp);
+    fclose (fp);
+  }
+
+  g_log_default_handler (log_domain, log_level, message, NULL);
+}
+
+/**
+ * gfs_simulation_run:
+ * @sim: a #GfsSimulation.
+ *
+ * Runs @sim.
+ */
+void gfs_simulation_run (GfsSimulation * sim)
+{
+  g_return_if_fail (sim != NULL);
+
+  guint id = g_log_set_handler ("Gfs", G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+				error_handler, sim);
+  gfs_clock_start (GFS_DOMAIN (sim)->timer);
+  gts_range_init (&GFS_DOMAIN (sim)->mpi_wait);
+  (* GFS_SIMULATION_CLASS (GTS_OBJECT (sim)->klass)->run) (sim);
+  gfs_clock_stop (GFS_DOMAIN (sim)->timer);
+  g_log_remove_handler ("Gfs", id);
+}
+
+/**
+ * gfs_simulation_map:
+ * @sim: a #GfsSimulation.
+ * @p: a #FttVector.
+ *
+ * Applies the mapping transformations associated with @sim to
+ * coordinates @p.
+ */
+void gfs_simulation_map (GfsSimulation * sim, FttVector * p)
+{
+  g_return_if_fail (sim != NULL);
+  g_return_if_fail (p != NULL);
+  
+  GSList * i = sim->maps->items;
+  while (i) {
+    (* GFS_MAP (i->data)->transform) (i->data, p, p);
+    i = i->next;
+  }
+  FttComponent c;
+  for (c = 0; c < 3; c++)
+    (&p->x)[c] *= (&GFS_DOMAIN (sim)->lambda.x)[c]/sim->physical_params.L;
+}
+
+/**
+ * gfs_simulation_map_inverse:
+ * @sim: a #GfsSimulation.
+ * @p: a #FttVector.
+ *
+ * Applies the inverse mapping transformations associated with @sim to
+ * coordinates @p.
+ */
+void gfs_simulation_map_inverse (GfsSimulation * sim, FttVector * p)
+{
+  g_return_if_fail (sim != NULL);
+  g_return_if_fail (p != NULL);
+  
+  FttComponent c;
+  for (c = 0; c < 3; c++)
+    (&p->x)[c] *= sim->physical_params.L/(&GFS_DOMAIN (sim)->lambda.x)[c];
+  GSList * i = sim->maps->items;
+  while (i) {
+    (* GFS_MAP (i->data)->inverse) (i->data, p, p);
+    i = i->next;
+  }
+}
+
+/**
+ * gfs_dimensional_value:
+ * @v: a #GfsVariable.
+ * @val: a non-dimensional value of @v.
+ *
+ * Returns: the dimensional value of @val according to the units of @v.
+ */
+gdouble gfs_dimensional_value (GfsVariable * v, gdouble val)
+{
+  g_return_val_if_fail (v != NULL, 0.);
+
+  gdouble L;
+  if (val == G_MAXDOUBLE || v->units == 0. || 
+      (L = GFS_SIMULATION (v->domain)->physical_params.L) == 1.)
+    return val;
+  return val*pow (L, v->units);
+}
+
+/**
+ * gfs_variable_is_dimensional:
+ * @v: a #GfsVariable.
+ *
+ * Returns: %TRUE if @v has dimensions, %FALSE otherwise.
+ */
+gboolean gfs_variable_is_dimensional (GfsVariable * v)
+{
+  g_return_val_if_fail (v != NULL, FALSE);
+
+  if (v->units == 0. || GFS_SIMULATION (v->domain)->physical_params.L == 1.)
+    return FALSE;
+  return TRUE;
+}
+
+/* GfsAdvection: Object */
+
+static void advection_run (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  gboolean streamfunction = FALSE;
+
+#if FTT_2D
+  GSList * i = domain->variables;
+  while (i && !streamfunction) {
+    streamfunction = (GFS_IS_VARIABLE_STREAM_FUNCTION (i->data) != NULL);
+    i = i->next;
+  }  
+#endif /* 2D */
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  /* ignore default advection scheme (use per tracer parameters only) */
+  sim->advection_params.scheme = GFS_NONE;
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+    if (!streamfunction) {
+      gfs_domain_face_traverse (domain, FTT_XYZ,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+      gfs_domain_face_traverse (domain, FTT_XYZ,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttFaceTraverseFunc) gfs_face_interpolated_normal_velocity,
+				gfs_domain_velocity (domain));
+    }
+    gfs_simulation_set_timestep (sim);
+
+    gfs_advance_tracers (domain, sim->advection_params.dt);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_half_do, sim);
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+}
+
+static void gfs_advection_class_init (GfsSimulationClass * klass)
+{
+  klass->run = advection_run;
+}
+
+GfsSimulationClass * gfs_advection_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_advection_info = {
+      "GfsAdvection",
+      sizeof (GfsSimulation),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) gfs_advection_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_advection_info);
+  }
+
+  return klass;
+}
+
+/* GfsPoisson: Object */
+
+static void rescale_div (FttCell * cell, gpointer * data)
+{
+  GfsVariable * divu = data[0];
+  GfsVariable * div = data[1];
+  GtsRange * vol = data[2];
+  gdouble size = ftt_cell_size (cell);
+
+  GFS_VARIABLE (cell, div->i) = GFS_VARIABLE (cell, divu->i)*size*size*(GFS_IS_MIXED (cell) ?
+									GFS_STATE (cell)->solid->a : 1.);
+  if (GFS_IS_MIXED (cell))
+    gts_range_add_value (vol, size*size*GFS_STATE (cell)->solid->a);
+  else
+    gts_range_add_value (vol, size*size);
+}
+
+static void add_ddiv (FttCell * cell, gpointer * data)
+{
+  GfsVariable * div = data[1];
+  gdouble * ddiv = data[2];
+  gdouble size = ftt_cell_size (cell);
+
+  if (GFS_IS_MIXED (cell))
+    GFS_VARIABLE (cell, div->i) += size*size*GFS_STATE (cell)->solid->a*(*ddiv);
+  else
+    GFS_VARIABLE (cell, div->i) += size*size*(*ddiv);
+}
+
+static void correct_div (GfsDomain * domain, GfsVariable * divu, GfsVariable * div)
+{
+  gpointer data[3];
+  GtsRange vol;
+  gdouble ddiv;
+
+  gts_range_init (&vol);
+  data[0] = divu;
+  data[1] = div;
+  data[2] = &vol;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) rescale_div, data);
+  gts_range_update (&vol);
+
+  ddiv = - gfs_domain_stats_variable (domain, div, FTT_TRAVERSE_LEAFS, -1).mean/vol.mean;
+  data[2] = &ddiv;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) add_ddiv, data);
+}
+
+static void copy_res (FttCell * cell, gpointer * data)
+{
+  GfsVariable * res = data[0], * res1 = data[1];
+  GFS_VARIABLE (cell, res->i) = GFS_VARIABLE (cell, res1->i);
+}
+
+static void poisson_run (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariable * dia, * div, * res = NULL, * res1, * p;
+  GfsMultilevelParams * par = &sim->approx_projection_params;
+  GSList * i;
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  i = domain->variables;
+  while (i) {
+    if (GFS_IS_VARIABLE_RESIDUAL (i->data))
+      res = i->data;
+    i = i->next;
+  }
+
+  p = gfs_variable_from_name (domain->variables, "P");
+  div = gfs_temporary_variable (domain);
+  correct_div (domain, gfs_variable_from_name (domain->variables, "Div"), div);
+  gfs_poisson_coefficients (domain, NULL);
+  res1 = gfs_temporary_variable (domain);
+  dia = gfs_temporary_variable (domain);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, dia);
+  /* compute residual */
+  par->depth = gfs_domain_depth (domain);  
+  gfs_residual (domain, par->dimension, FTT_TRAVERSE_LEAFS, -1, p, div, dia, res1);
+  /* solve for pressure */
+  par->residual_before = par->residual = 
+    gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, 1., res1);
+  par->niter = 0;
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend &&
+	 sim->time.i < par->nitermax &&
+	 par->residual.infty > par->tolerance) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    if (res) {
+      gpointer data[2];
+      data[0] = res;
+      data[1] = res1;
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) copy_res, data);
+    }
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    gfs_domain_timer_start (domain, "poisson_cycle");
+    gfs_poisson_cycle (domain, par, p, div, dia, res1);
+    par->residual = gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, 1., res1);
+    gfs_domain_timer_stop (domain, "poisson_cycle");
+
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+    gfs_simulation_adapt (sim);
+
+    par->niter++;
+    sim->time.t = sim->tnext;
+    sim->time.i++;
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events),
+			 (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (dia));
+  gts_object_destroy (GTS_OBJECT (div));
+  gts_object_destroy (GTS_OBJECT (res1));
+}
+
+static void poisson_class_init (GfsSimulationClass * klass)
+{
+  klass->run = poisson_run;
+}
+
+static void poisson_init (GfsDomain * domain)
+{
+  gfs_domain_add_variable (domain, "Div", "Right-hand-side of the Poisson equation");
+}
+
+GfsSimulationClass * gfs_poisson_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_poisson_info = {
+      "GfsPoisson",
+      sizeof (GfsSimulation),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) poisson_class_init,
+      (GtsObjectInitFunc) poisson_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_poisson_info);
+  }
+
+  return klass;
+}
+
+/* GfsAxi: Object */
+
+static void axi_read (GtsObject ** object, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_axi_class ())->parent_class->read) (object, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_DOMAIN (*object)->refpos.y = 0.5;
+}
+
+static gdouble axi_face_metric (const GfsDomain * domain, const FttCellFace * face)
+{
+  FttVector p;
+  ftt_face_pos (face, &p);
+  return p.y;
+}
+
+static gdouble axi_cell_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  FttVector p;
+  gfs_cell_cm (cell, &p);
+  return p.y;
+}
+
+static gdouble axi_solid_metric (const GfsDomain * domain, const FttCell * cell)
+{
+  g_assert (GFS_IS_MIXED (cell));
+  return GFS_STATE (cell)->solid->ca.y;
+}
+
+static void axi_class_init (GfsSimulationClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = axi_read;
+}
+
+static void axi_init (GfsDomain * domain)
+{
+  domain->face_metric  = axi_face_metric;
+  domain->cell_metric  = axi_cell_metric;
+  domain->solid_metric = axi_solid_metric;
+}
+
+GfsSimulationClass * gfs_axi_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_axi_info = {
+      "GfsAxi",
+      sizeof (GfsSimulation),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) axi_class_init,
+      (GtsObjectInitFunc) axi_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_axi_info);
+  }
+
+  return klass;
+}
diff --git a/src/simulation.h b/src/simulation.h
new file mode 100644
index 0000000..f01c08d
--- /dev/null
+++ b/src/simulation.h
@@ -0,0 +1,154 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __SIMULATION_H__
+#define __SIMULATION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "domain.h"
+#include "timestep.h"
+
+#ifndef __EVENT_H__
+  typedef struct _GfsSimulation         GfsSimulation;
+#endif
+typedef struct _GfsSimulationClass    GfsSimulationClass;
+typedef struct _GfsTime               GfsTime;
+typedef struct _GfsPhysicalParams     GfsPhysicalParams;
+typedef struct _GfsAdaptStats         GfsAdaptStats;
+
+struct _GfsTime {
+  gdouble t, start, end;
+  guint i, istart, iend;
+  gdouble dtmax;
+};
+
+struct _GfsPhysicalParams {
+  gdouble L, g;
+  GfsFunction * alpha;
+};
+
+struct _GfsAdaptStats {
+  guint removed, created;
+  GtsRange cmax;
+  GtsRange ncells;
+};
+
+struct _GfsSimulation {
+  GfsDomain parent;
+
+  GfsTime time;
+  GfsPhysicalParams physical_params;
+
+  GfsMultilevelParams projection_params;
+  GfsMultilevelParams approx_projection_params;
+
+  GfsAdvectionParams advection_params;
+
+  GtsSListContainer * refines;
+
+  GtsSListContainer * adapts;
+  GfsAdaptStats adapts_stats;
+
+  GtsSListContainer * events, * maps;
+  GSList * modules, * globals, * preloaded_modules;
+
+  GtsSListContainer * solids;
+  guint thin;
+  gboolean output_solid;
+
+  gboolean deferred_compilation;
+
+  gdouble tnext;
+};
+
+struct _GfsSimulationClass {
+  GfsDomainClass parent_class;
+
+  void    (* run) (GfsSimulation *);
+  gdouble (* cfl) (GfsSimulation *);
+};
+
+#define GFS_SIMULATION(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsSimulation,\
+					           gfs_simulation_class ())
+#define GFS_SIMULATION_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						   GfsSimulationClass,\
+						   gfs_simulation_class())
+#define GFS_IS_SIMULATION(obj)         (gts_object_is_from_class (obj,\
+						   gfs_simulation_class ()))
+
+void                 gfs_advance_tracers         (GfsDomain * domain, 
+						  gdouble dt);
+GfsSimulationClass * gfs_simulation_class        (void);
+GfsSimulation *      gfs_simulation_new          (GfsSimulationClass * klass);
+void                 gfs_simulation_init         (GfsSimulation * sim);
+void                 gfs_simulation_write        (GfsSimulation * sim,
+						  gint max_depth,  
+						  FILE * fp);
+void                 gfs_simulation_union_write  (GfsSimulation * sim,
+						  gint max_depth,  
+						  FILE * fp);
+GfsSimulation *      gfs_simulation_read         (GtsFile * fp);
+GSList *             gfs_simulation_get_solids   (GfsSimulation * sim);
+void                 gfs_simulation_refine       (GfsSimulation * sim);
+void                 gfs_simulation_set_timestep (GfsSimulation * sim);
+void                 gfs_simulation_map          (GfsSimulation * sim, 
+						  FttVector * p);
+void                 gfs_simulation_map_inverse  (GfsSimulation * sim, 
+						  FttVector * p);
+gdouble              gfs_dimensional_value       (GfsVariable * v, 
+						  gdouble val);
+gboolean             gfs_variable_is_dimensional (GfsVariable * v);
+void                 gfs_time_init               (GfsTime * t);
+void                 gfs_time_write              (GfsTime * t, 
+						  FILE * fp);
+void                 gfs_time_read               (GfsTime * t, 
+						  GtsFile * fp);
+void                 gfs_physical_params_init    (GfsPhysicalParams * p);
+void                 gfs_physical_params_write   (GfsPhysicalParams * p, 
+						  FILE * fp);
+void                 gfs_physical_params_read    (GfsPhysicalParams * p,
+						  GfsDomain * domain,
+						  GtsFile * fp);
+void                 gfs_simulation_run          (GfsSimulation * sim);
+#define              gfs_object_simulation(o)     GFS_SIMULATION(GTS_OBJECT (o)->reserved)
+#define              gfs_object_simulation_set(o,s) (GTS_OBJECT (o)->reserved = (s))
+
+/* GfsAdvection: Header */
+
+GfsSimulationClass * gfs_advection_class          (void);
+
+/* GfsPoisson: Header */
+
+GfsSimulationClass * gfs_poisson_class            (void);
+
+/* GfsAxi: Header */
+
+#define GFS_IS_AXI(obj)          (gts_object_is_from_class (obj, gfs_axi_class ()))
+
+GfsSimulationClass * gfs_axi_class                (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SIMULATION_H__ */
diff --git a/src/solid.c b/src/solid.c
new file mode 100644
index 0000000..624c3bd
--- /dev/null
+++ b/src/solid.c
@@ -0,0 +1,1577 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "solid.h"
+#include "vof.h"
+#include "variable.h"
+
+/**
+ * gfs_cell_fluid:
+ * @cell: a #FttCell.
+ * 
+ * Sets @cell and all its descendants as full fluid cells.
+ */
+void gfs_cell_fluid (FttCell * cell)
+{
+  g_return_if_fail (cell != NULL);
+
+  if (GFS_STATE (cell)->solid) {
+    g_free (GFS_STATE (cell)->solid);
+    GFS_STATE (cell)->solid = NULL;
+  }
+
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren child;
+    guint i;
+ 
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i])
+	gfs_cell_fluid (child.c[i]);
+  }
+}
+
+typedef struct {
+  GtsPoint p[4];
+  GfsSegment s[4];
+} CellFace;
+
+static void face_fractions (CellFace * f, GfsSolidVector * solid, FttVector * h)
+{
+  static guint etod[] = { 3, 0, 2, 1 };
+  guint k, m;
+  gboolean ins;
+  guint o = 0;
+  GtsPoint r[2];
+  gdouble a, x0 = f->p[0].x, y0 = f->p[0].y;
+  
+  solid->a = 0.;
+  solid->cm.x = solid->cm.y = solid->cm.z = 0.;
+  solid->ca.z = 0.;
+      
+  for (m = 0; m < 4 && f->s[m].n == 0; m++);
+  ins = f->s[m].inside < 0;
+  for (k = m; k < m + 4; k++) {
+    guint i = k % 4, i1 = (i + 1) % 4;
+    gdouble x1 = f->p[i].x - x0, y1 = f->p[i].y - y0, x2 = f->p[i1].x - x0, y2 = f->p[i1].y - y0;
+    if (f->s[i].n > 0) {
+      g_assert (ins == (f->s[i].inside < 0));
+      solid->s[etod[i]] = ins ? f->s[i].x : 1. - f->s[i].x;
+      r[o].x = x1 + f->s[i].x*(x2 - x1);
+      r[o].y = y1 + f->s[i].x*(y2 - y1);
+      if (ins) {
+	x2 = r[o].x; y2 = r[o].y;
+      }
+      else {
+	x1 = r[o].x; y1 = r[o].y;
+      }
+      solid->a += (x1 + x2)*(y2 - y1);
+      solid->cm.x += (x1 - x2)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+      solid->cm.y += (y2 - y1)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+      o++;
+      if (o == 2) {
+	o = 0;
+	if (ins) {
+	  x1 = r[1].x; y1 = r[1].y;
+	  x2 = r[0].x; y2 = r[0].y;	    
+	}
+	else {
+	  x1 = r[0].x; y1 = r[0].y;
+	  x2 = r[1].x; y2 = r[1].y;	    
+	}
+	solid->a += (x1 + x2)*(y2 - y1);
+	solid->cm.x += (x1 - x2)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+	solid->cm.y += (y2 - y1)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+	solid->ca.x = (x1 + x2)/2.;
+	solid->ca.y = (y1 + y2)/2.;
+      }
+      ins = !ins;
+    }
+    else if (ins) {
+      solid->s[etod[i]] = 1.;
+      solid->a += (x1 + x2)*(y2 - y1);
+      solid->cm.x += (x1 - x2)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+      solid->cm.y += (y2 - y1)*(2.*(x1*y1 + x2*y2) + x1*y2 + x2*y1);
+    }
+    else
+      solid->s[etod[i]] = 0.;
+  }
+  
+  a = solid->a < 0. ? 0. : solid->a/(2.*h->x*h->y);
+  solid->ca.x += x0;
+  solid->ca.y += y0;
+  if (a > 1e-4) {
+    solid->cm.x = x0 + solid->cm.x/(3.*solid->a);
+    solid->cm.y = y0 + solid->cm.y/(3.*solid->a);
+  }
+  else {
+    guint n = 0;
+
+    solid->cm.x = solid->cm.y = 0.;
+    for (m = 0; m < 4 && f->s[m].n == 0; m++);
+    ins = f->s[m].inside < 0;
+    for (k = m; k < m + 4; k++) {
+      guint i = k % 4, i1 = (i + 1) % 4;
+      gdouble x1 = f->p[i].x - x0, y1 = f->p[i].y - y0, x2 = f->p[i1].x - x0, y2 = f->p[i1].y - y0;
+      if (f->s[i].n > 0) {
+	gdouble x = x1 + f->s[i].x*(x2 - x1);
+	gdouble y = y1 + f->s[i].x*(y2 - y1);
+
+	g_assert (ins == (f->s[i].inside < 0));
+	solid->cm.x += x;
+	solid->cm.y += y;
+	n++;
+	if (ins) {
+	  solid->cm.x += x1;
+	  solid->cm.y += y1;
+	  n++;
+	}
+	ins = !ins;
+      }
+      else if (ins) {
+	solid->cm.x += x1;
+	solid->cm.y += y1;
+	n++;
+      }
+    }
+    g_assert (n > 0);
+    solid->cm.x = x0 + solid->cm.x/n;
+    solid->cm.y = y0 + solid->cm.y/n;
+  }
+  solid->a = a;
+}
+
+static void face_new (CellFace * f, FttCell * cell, GfsGenericSurface * s, FttVector * h)
+{
+  FttVector p;
+  guint i;
+
+  ftt_cell_pos (cell, &p);
+  f->p[0].x = p.x - h->x/2.; f->p[0].y = p.y - h->y/2.; f->p[0].z = 0.;
+  f->p[1].x = p.x + h->x/2.; f->p[1].y = p.y - h->y/2.; f->p[1].z = 0.;
+  f->p[2].x = p.x + h->x/2.; f->p[2].y = p.y + h->y/2.; f->p[2].z = 0.;
+  f->p[3].x = p.x - h->x/2.; f->p[3].y = p.y + h->y/2.; f->p[3].z = 0.;
+
+  for (i = 0; i < 4; i++) {
+    f->s[i].E = &f->p[i];
+    f->s[i].D = &f->p[(i + 1) % 4];
+    gfs_surface_segment_intersection (s, cell, &f->s[i]);
+  }
+}
+
+static gboolean solid_face_is_thin (CellFace * f)
+{
+  guint odd = 0, even = 0, i;
+
+  for (i = 0; i < 4; i++)
+    if (f->s[i].n) {
+      if (f->s[i].n % 2 != 0)
+	odd++;
+      else
+	even++;
+    }
+  if (odd == 2 && even == 1) {
+    for (i = 0; i < 4; i++)
+      if (f->s[i].n % 2 != 0 && f->s[(i + 2) % 4].n % 2 != 0)
+	return FALSE;
+    return TRUE;
+  }
+  return (odd > 2 || even > 1);
+}
+
+/**
+ * gfs_set_2D_solid_fractions_from_surface:
+ * @cell: a #FttCell.
+ * @s: a #GfsGenericSurface.
+ *
+ * Sets the 2D volume fractions of @cell cut by @s.
+ *
+ * Returns: %TRUE if the cell is thin, %FALSE otherwise;
+ */
+gboolean gfs_set_2D_solid_fractions_from_surface (FttCell * cell,
+						  GfsGenericSurface * s)
+{
+  GfsSolidVector * solid;
+  FttVector h;
+  CellFace f;
+  guint i, n1 = 0;
+  gboolean thin = FALSE;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+  g_return_val_if_fail (s != NULL, FALSE);
+
+  h.x = h.y = ftt_cell_size (cell);
+  face_new (&f, cell, s, &h);
+  
+  for (i = 0; i < 4; i++)
+    if (f.s[i].n % 2 != 0) {
+      f.s[i].x /= f.s[i].n;
+      n1++;
+    }
+    else
+      f.s[i].n = 0;
+
+  solid = GFS_STATE (cell)->solid;
+  switch (n1) {
+  case 0:
+    break;
+  case 4:
+    thin = TRUE;
+    /* fall through */
+  case 2: {
+    if (!solid)
+      GFS_STATE (cell)->solid = solid = g_malloc0 (sizeof (GfsSolidVector));
+    face_fractions (&f, solid, &h);
+    if (solid->a == 1.) {
+      g_free (solid);
+      GFS_STATE (cell)->solid = NULL;
+    }
+    break;
+  }
+  default: {
+    FttVector p;
+    ftt_cell_pos (cell, &p);
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	   "the surface may not be closed (n1 = %d)\n"
+	   "at (%g,%g,%g)", n1, p.x, p.y, p.z);
+  }
+  }
+  return thin;
+}
+
+typedef struct {
+  gboolean destroy_solid;
+  FttCellCleanupFunc cleanup;
+  gpointer data;
+  GfsVariable * status;
+  guint thin;
+  GSList * solid_boxes;
+} InitSolidParams;
+
+static gboolean thin_cell_is_solid (FttCell * cell)
+{
+  gdouble sum = 0.;
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    sum += GFS_STATE (cell)->solid->s[d];
+  return (sum < FTT_NEIGHBORS/2);
+}
+
+static void deal_with_thin_cell (FttCell * cell, InitSolidParams * p)
+{
+  cell->flags |= GFS_FLAG_THIN;
+  if (thin_cell_is_solid (cell))
+    GFS_VALUE (cell, p->status) = GFS_STATUS_SOLID;
+  else {
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+    FttDirection d;
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      solid->s[d] = (solid->s[d] > 0.5);
+    solid->a = 1.;
+    ftt_cell_pos (cell, &solid->cm);
+    solid->ca = solid->cm;
+  }
+}
+
+#if FTT_2D /* 2D */
+
+static void set_solid_fractions_from_surface (FttCell * cell,
+					      GfsGenericSurface * s,
+					      InitSolidParams * p)
+{
+  if (gfs_set_2D_solid_fractions_from_surface (cell, s)) {
+    p->thin++;
+    deal_with_thin_cell (cell, p);
+  }
+  else if (GFS_STATE (cell)->solid && GFS_STATE (cell)->solid->a == 0.)
+    GFS_VALUE (cell, p->status) = GFS_STATUS_SOLID;
+}
+
+/**
+ * gfs_solid_is_thin:
+ * @cell: a #FttCell.
+ * @s: a #GfsGenericSurface.
+ *
+ * @s is "thin" relative to @cell if the miminum distance between
+ * non-connected faces of @s cutting @cell is smaller than the size of
+ * @cell (see doc/figures/thin.fig).
+ *
+ * Returns: %TRUE if @s is a thin surface, %FALSE otherwise.
+ */
+gboolean gfs_solid_is_thin (FttCell * cell, GfsGenericSurface * s)
+{
+  CellFace f;
+  FttVector h;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+  g_return_val_if_fail (s != NULL, FALSE);
+
+  h.x = h.y = ftt_cell_size (cell);
+  face_new (&f, cell, s, &h);
+  return solid_face_is_thin (&f);
+}
+
+#else /* 2D3 or 3D */
+#include "isocube.h"
+
+typedef struct {
+  GtsPoint p[8];
+  GfsSegment s[12];
+} CellCube;
+
+static void rotate (CellFace * f, FttVector * h, FttComponent c)
+{
+  guint i;
+
+  switch (c) {
+  case FTT_X: 
+    for (i = 0; i < 4; i++) {
+      f->p[i].x = f->p[i].y; f->p[i].y = f->p[i].z;
+    }
+    h->x = h->y; h->y = h->z;
+    break;
+  case FTT_Y:
+    for (i = 0; i < 4; i++)
+      f->p[i].y = f->p[i].z;
+    h->y = h->z;
+    break;
+  case FTT_Z:
+    break;
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void cell_size (FttCell * cell, FttVector * h)
+{
+  h->x = h->y = ftt_cell_size (cell);
+#if FTT_2D3
+  h->z = 1.;
+#else  /* 3D */
+  h->z = h->x;
+#endif /* 3D */
+}
+
+/* Returns: the number of closed loops for the given isocube
+ * 
+ * Fixme: this algorithm is not correct in general. This has no
+ * consequence for this particular application because we also check
+ * that the isosurface is "planar" together with use of topology() in
+ * set_solid_fractions_from_surface3D(), however this is important in
+ * general.
+ *
+ * The bug is triggered for certain configurations of "non-planar"
+ * isosurfaces.
+ */
+static guint topology (CellCube * cube)
+{
+  guint l, nl = 0;
+  gboolean used[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
+  
+  for (l = 0; l < 12; l++) {
+    guint nv = 0, e = l, cut = cube->s[e].n % 2;
+    
+    while (cut && !used[e]) {
+      guint m = 0, * ne = connect[e][cube->s[e].inside > 0];
+
+      nv++;
+      used[e] = TRUE;
+      cut = 0;
+      while (m < 3 && !cut) {
+	e = ne[m++];
+	cut = cube->s[e].n % 2;
+      }
+    }
+    if (nv > 2)
+      nl++;
+  }
+  return nl;
+}
+
+static void cube_new (CellCube * cube, FttCell * cell, GfsGenericSurface * s, FttVector * o, FttVector * h)
+{
+  guint i;
+
+  for (i = 0; i < FTT_DIMENSION; i++)
+    (&o->x)[i] -= (&h->x)[i]/2.;
+  for (i = 0; i < 8; i++) { /* for each vertex of the cube */
+    cube->p[i].x = o->x + h->x*vertex[i].x;
+    cube->p[i].y = o->y + h->y*vertex[i].y;
+    cube->p[i].z = o->z + h->z*vertex[i].z;
+  }
+
+  for (i = 0; i < 12; i++) {
+    cube->s[i].E = &cube->p[edge1[i][0]];
+    cube->s[i].D = &cube->p[edge1[i][1]];
+    gfs_surface_segment_intersection (s, cell, &cube->s[i]);
+  }
+}
+
+static void set_solid_fractions_from_surface (FttCell * cell, 
+					      GfsGenericSurface * surface, 
+					      InitSolidParams * p)
+{
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+  CellCube cube;
+  FttVector o, ca = {0., 0., 0.}, h;
+  guint i, n1 = 0;
+  gint inside[8] = {0,0,0,0,0,0,0,0};
+  gboolean planar = TRUE;
+
+  ftt_cell_pos (cell, &o);
+  cell_size (cell, &h);
+  cube_new (&cube, cell, surface, &o, &h);
+
+  for (i = 0; i < 12; i++) { /* for each edge of the cube */
+    GfsSegment * s = &cube.s[i];
+    if (cube.s[i].n % 2 != 0) { /* only for odd number of intersections */
+      guint j = edge1[i][0], k = edge1[i][1];
+
+      /* intersection vertex position is the average of all the n[i] intersections */
+      s->x /= s->n;
+
+      /* average of all intersections */
+      ca.x += (1. - s->x)*cube.p[j].x + s->x*cube.p[k].x;
+      ca.y += (1. - s->x)*cube.p[j].y + s->x*cube.p[k].y;
+      ca.z += (1. - s->x)*cube.p[j].z + s->x*cube.p[k].z;
+
+      g_assert (inside[j] == 0 || inside[j] == s->inside);
+      g_assert (inside[k] == 0 || inside[k] == - s->inside);
+      inside[j] = s->inside;
+      inside[k] = - s->inside;
+      n1++;
+    }
+    else
+      s->n = 0;
+  }
+
+  if (n1 == 0) { /* no intersections */
+    if (solid) {
+      g_free (solid);
+      GFS_STATE (cell)->solid = NULL;      
+    }
+    return;
+  }
+
+  if (!solid)
+    GFS_STATE (cell)->solid = solid = g_malloc0 (sizeof (GfsSolidVector));
+
+  /* compute face fractions */
+  for (i = 0; i < FTT_NEIGHBORS; i++) {
+    CellFace f;
+    guint j, n2;
+
+    n2 = 0;
+    for (j = 0; j < 4; j++) { /* initialise face i */
+      GfsSegment * s = &cube.s[face[i][j][0]];
+
+      f.p[j] = cube.p[face_v[i][j]];
+      f.s[j].n = s->n;
+      if (f.s[j].n) n2++;
+      if (face[i][j][1]) {
+	f.s[j].x = 1. - s->x;
+	f.s[j].inside = - s->inside;
+      }
+      else {
+	f.s[j].x = s->x;
+	f.s[j].inside = s->inside;
+      }
+    }
+
+    switch (n2) {
+    case 0: { /* the face is not cut */
+      gint ins = 0;
+
+      /* checks whether the face vertices are inside or outside */
+      for (j = 0; j < 4; j++) {
+	gint k = inside[face_v[i][j]];
+	if (k) {
+	  g_assert (ins == 0 || ins == k);
+	  ins = k;
+	}
+      }
+      g_assert (ins != 0);
+      solid->s[i] = ins > 0 ? 0. : 1.;
+      break;
+    }
+    case 4:
+      planar = FALSE;
+      /* fall through */
+    case 2: { /* the face is cut 2 or 4 times */
+      GfsSolidVector sol;
+      FttVector h1;
+
+      h1 = h;
+      rotate (&f, &h1, i/2);
+      face_fractions (&f, &sol, &h1);
+      solid->s[i] = sol.a;
+      break;
+    }
+    default: {
+      FttVector p;
+      ftt_cell_pos (cell, &p);
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
+	     "the surface may not be closed (n2 = %d)\n"
+	     "at (%g,%g,%g)", n2, p.x, p.y, p.z);
+    }
+    }
+  }
+
+  /* now compute cell fraction, center of area, center of mass */
+  ca.x /= n1; ca.y /= n1; ca.z /= n1; 
+  solid->ca = ca;
+  if (planar && topology (&cube) == 1) {
+    FttVector m;
+    gdouble alpha, n = 0.;
+    gboolean sym[FTT_DIMENSION];
+    FttComponent c;
+
+    for (c = 0; c < FTT_DIMENSION; c++) {
+      (&ca.x)[c] = ((&ca.x)[c] - (&o.x)[c])/(&h.x)[c];
+      (&m.x)[c] = solid->s[2*c + 1] - solid->s[2*c];
+      if ((&m.x)[c] < 0.) {
+	(&m.x)[c] = - (&m.x)[c];
+	(&ca.x)[c] = 1. - (&ca.x)[c];
+	sym[c] = TRUE;
+      }
+      else
+	sym[c] = FALSE;
+      n += (&m.x)[c];
+    }
+    if (n == 0.) { /* this is a fluid or solid cell */
+      for (c = 1; c < FTT_NEIGHBORS; c++)
+	g_assert (solid->s[c] == solid->s[0]);
+      if (solid->s[0] == 1.) { /* fluid */
+	g_free (solid);
+	GFS_STATE (cell)->solid = NULL;
+	return;
+      }
+      else { /* solid */
+	solid->a = 0.;
+	solid->cm.x = solid->cm.y = solid->cm.z = 0.;
+      }
+    }
+    else {
+      m.x /= n; m.y /= n; m.z /= n;
+      alpha = m.x*ca.x + m.y*ca.y + m.z*ca.z;
+      solid->a = gfs_plane_volume (&m, alpha);
+      gfs_plane_center (&m, alpha, solid->a, &solid->cm);
+    }
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&solid->cm.x)[c] = (&o.x)[c] + 
+	(sym[c] ? 1. - (&solid->cm.x)[c] : (&solid->cm.x)[c])*(&h.x)[c];
+  }
+  else { /* this is a "thin" cell */
+    p->thin++;
+    deal_with_thin_cell (cell, p);
+  }
+  if (solid->a == 0.)
+    GFS_VALUE (cell, p->status) = GFS_STATUS_SOLID;
+}
+
+/**
+ * gfs_solid_is_thin:
+ * @cell: a #FttCell.
+ * @s: a #GfsGenericSurface.
+ *
+ * @s is "thin" relative to @cell if the miminum distance between
+ * non-connected faces of @s cutting @cell is smaller than the size of
+ * @cell (see doc/figures/thin.fig).
+ *
+ * Returns: %TRUE if @s is a thin surface, %FALSE otherwise.
+ */
+gboolean gfs_solid_is_thin (FttCell * cell, GfsGenericSurface * s)
+{
+  CellCube cube;
+  FttVector o, h;
+  guint i;
+
+  g_return_val_if_fail (cell != NULL, FALSE);
+  g_return_val_if_fail (s != NULL, FALSE);
+
+  ftt_cell_pos (cell, &o);
+  cell_size (cell, &h);
+  cube_new (&cube, cell, s, &o, &h);
+  for (i = 0; i < FTT_NEIGHBORS; i++) {
+    CellFace f;
+    guint j;
+
+    for (j = 0; j < 4; j++)
+      f.s[j].n = cube.s[face[i][j][0]].n;
+    if (solid_face_is_thin (&f))
+      return TRUE;
+  }
+  return (topology (&cube) > 1);
+}
+
+#endif /* 2D3 or 3D */
+
+static gdouble solid_sa (GfsSolidVector * s)
+{
+  gdouble sa2 = 0.;
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    gdouble n = s->s[2*c] - s->s[2*c + 1];
+
+    sa2 += n*n;
+  }
+  return sqrt (sa2);
+}
+
+/**
+ * gfs_cell_init_solid_fractions_from_children:
+ * @cell: a #FttCell.
+ *
+ * Uses the values of the solid fractions of the children of @cell to
+ * compute the values of its solid fractions.
+ *
+ * This function fails if @cell is a leaf of the cell tree.  
+ */
+void gfs_cell_init_solid_fractions_from_children (FttCell * cell)
+{
+  FttCellChildren child;
+  guint i, j;
+  gdouble w = 0., wa = 0.;
+  gboolean cell_is_solid = TRUE;
+  gboolean cell_is_mixed = FALSE;
+  FttVector cm = { 0., 0., 0.};
+  FttVector ca = { 0., 0., 0.};
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (!FTT_CELL_IS_LEAF (cell));
+
+  ftt_cell_children (cell, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i]) {
+      if (GFS_IS_FLUID (child.c[i])) {
+	FttVector p;
+
+	w += 1.;
+	ftt_cell_pos (child.c[i], &p);
+	cm.x += p.x; cm.y += p.y; cm.z += p.z;
+	cell_is_solid = FALSE;
+      }
+      else {
+	GfsSolidVector * solid = GFS_STATE (child.c[i])->solid;
+	gdouble sa = solid_sa (solid) + 1e-9;
+
+	w += solid->a; wa += sa;
+	cm.x += solid->cm.x*solid->a;
+	cm.y += solid->cm.y*solid->a;
+	cm.z += solid->cm.z*solid->a;
+	ca.x += solid->ca.x*sa;
+	ca.y += solid->ca.y*sa;
+	ca.z += solid->ca.z*sa;
+	cell_is_mixed = TRUE;
+      }
+    }
+
+  if (cell_is_mixed) {
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+    if (solid == NULL)
+      GFS_STATE (cell)->solid = solid = g_malloc0 (sizeof (GfsSolidVector));
+
+    solid->a = w/FTT_CELLS;
+    g_assert (wa > 0.);
+    solid->ca.x = ca.x/wa;
+    solid->ca.y = ca.y/wa;
+    solid->ca.z = ca.z/wa;
+    if (w > 0.) {
+      solid->cm.x = cm.x/w;
+      solid->cm.y = cm.y/w;
+      solid->cm.z = cm.z/w;
+    }
+    else
+      ftt_cell_pos (cell, &solid->cm);
+
+    for (i = 0; i < FTT_NEIGHBORS; i++) {
+      guint n = ftt_cell_children_direction (cell, i, &child);
+
+      w = 0.;
+      for (j = 0; j < n; j++)
+	if (child.c[j])
+	  w += GFS_IS_FLUID (child.c[j]) ? 1. : GFS_STATE (child.c[j])->solid->s[i];
+      solid->s[i] = w/n;
+    }
+  }
+  else { /* !cell_is_mixed */
+    if (GFS_STATE (cell)->solid) {
+      g_free (GFS_STATE (cell)->solid);
+      GFS_STATE (cell)->solid = NULL;
+    }
+    g_assert (!cell_is_solid);
+  }
+}
+
+static void push_leaf (GtsFifo * fifo, FttCell * cell, FttDirection d, gdouble a,
+		       GfsVariable * status)
+{
+  if (FTT_CELL_IS_LEAF (cell)) {
+    if (!GFS_IS_MIXED (cell) && GFS_VALUE (cell, status) == GFS_STATUS_UNDEFINED) {
+      GFS_VALUE (cell, status) = a;
+      gts_fifo_push (fifo, cell);
+    }
+  }
+  else {
+    FttCellChildren child;
+    guint i, n;
+    
+    n = ftt_cell_children_direction (cell, FTT_OPPOSITE_DIRECTION (d), &child);
+    for (i = 0; i < n; i++)
+      if (child.c[i] && !GFS_IS_MIXED (child.c[i]) && 
+	  GFS_VALUE (child.c[i], status) == GFS_STATUS_UNDEFINED) {
+	g_assert (FTT_CELL_IS_LEAF (child.c[i]));
+	GFS_VALUE (child.c[i], status) = a;
+	gts_fifo_push (fifo, child.c[i]);
+      }
+  }
+}
+
+static void paint_leaf (GtsFifo * fifo, gdouble a, GfsVariable * status)
+{
+  FttCell * cell;
+
+  while ((cell = gts_fifo_pop (fifo))) {
+    FttDirection i;
+    FttCellNeighbors n;
+    
+    ftt_cell_neighbors (cell, &n);
+    for (i = 0; i < FTT_NEIGHBORS; i++)
+      if (n.c[i] && !GFS_CELL_IS_BOUNDARY (n.c[i]))
+	push_leaf (fifo, n.c[i], i, a, status);
+  }
+}
+
+static void paint_mixed_leaf (FttCell * cell, GfsVariable * status)
+{
+  if (GFS_IS_MIXED (cell)) {
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+    GtsFifo * fifo;
+    FttCell * n;
+    FttDirection i;
+
+    fifo = gts_fifo_new ();
+    for (i = 0; i < FTT_NEIGHBORS; i++)
+      if ((n = ftt_cell_neighbor (cell, i)) && !GFS_CELL_IS_BOUNDARY (n)) {
+	if (solid->s[i] == 0. || solid->s[i] == 1.) {
+	  push_leaf (fifo, n, i, solid->s[i] + 1., status);
+	  paint_leaf (fifo, solid->s[i] + 1., status);
+	}
+	else if (!FTT_CELL_IS_LEAF (n)) {
+	  FttCellChildren child;
+	  guint j, k;
+	  gdouble w = 0.;
+
+	  k = ftt_cell_children_direction (n, FTT_OPPOSITE_DIRECTION (i), &child);
+	  for (j = 0; j < k; j++)
+	    if (child.c[j])
+	      w += GFS_IS_FLUID (child.c[j]) ? 1. : 
+		GFS_STATE (child.c[j])->solid->s[FTT_OPPOSITE_DIRECTION (i)];
+	  if (w/k <= 0. || w/k >= 1.)
+	    g_warning ("file %s: line %d (%s): w/k=%g solid->s[%d]=%g",
+		       __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		       w/k, i, solid->s[i]);
+	  solid->s[i] = w/k;
+	}
+      }
+    gts_fifo_destroy (fifo);
+  }
+}
+
+static void solid_fractions_from_children (FttCell * cell, InitSolidParams * p)
+{
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren child;
+    guint i;
+    
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i])
+	solid_fractions_from_children (child.c[i], p);
+    if (FTT_CELL_IS_LEAF (cell))
+      /* all the children have been destroyed i.e. the cell is solid */
+      GFS_VALUE (cell, p->status) = GFS_STATUS_SOLID;
+    else {
+      gfs_cell_init_solid_fractions_from_children (cell);
+      GFS_VALUE (cell, p->status) = GFS_STATUS_UNDEFINED;
+      if (!p->destroy_solid && !GFS_IS_MIXED (cell)) {
+	ftt_cell_children (cell, &child);
+	for (i = 0; i < FTT_CELLS; i++)
+	  if (child.c[i]) {
+	    if (GFS_VALUE (cell, p->status) == GFS_STATUS_UNDEFINED)
+	      GFS_VALUE (cell, p->status) = GFS_VALUE (child.c[i], p->status);
+	    else
+	      g_assert (GFS_VALUE (cell, p->status) == GFS_VALUE (child.c[i], p->status));
+	  }
+      }
+    }
+  }
+  if (p->destroy_solid && 
+      GFS_VALUE (cell, p->status) == GFS_STATUS_SOLID && 
+      !FTT_CELL_IS_ROOT (cell))
+    ftt_cell_destroy (cell, p->cleanup, p->data);
+}
+
+static void foreach_box (GfsBox * box, InitSolidParams * p)
+{
+  solid_fractions_from_children (box->root, p);
+  if (p->destroy_solid && GFS_VALUE (box->root, p->status) == GFS_STATUS_SOLID)
+    p->solid_boxes = g_slist_prepend (p->solid_boxes, box);
+}
+
+static void match_fractions (FttCell * cell, GfsVariable * status)
+{
+  if (GFS_IS_MIXED (cell)) {
+    FttCellNeighbors neighbor;
+    GfsSolidVector * solid = GFS_STATE (cell)->solid;
+    FttDirection d;
+
+    ftt_cell_neighbors (cell, &neighbor);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (neighbor.c[d] && !GFS_CELL_IS_BOUNDARY (neighbor.c[d])) {
+	if (!FTT_CELL_IS_LEAF (neighbor.c[d])) {
+	  FttCellChildren child;
+	  FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+	  guint i, n = ftt_cell_children_direction (neighbor.c[d], od, &child);
+	  gdouble s = 0.;
+
+	  g_assert (GFS_VARIABLE (neighbor.c[d], status->i) != 1.);
+	  for (i = 0; i < n; i++)
+	    if (child.c[i] && GFS_VARIABLE (child.c[i], status->i) != 1.)
+	      s += GFS_IS_MIXED (child.c[i]) ? GFS_STATE (child.c[i])->solid->s[od] : 1.;
+	  solid->s[d] = s/n;
+	}
+	else if (GFS_VARIABLE (neighbor.c[d], status->i) != 1.) {
+	  if (!GFS_IS_MIXED (neighbor.c[d]) && solid->s[d] < 1.)
+	    solid->s[d] = 1.;
+	  else if (neighbor.c[d]->flags & GFS_FLAG_THIN)
+	    solid->s[d] = GFS_STATE (neighbor.c[d])->solid->s[FTT_OPPOSITE_DIRECTION (d)];
+	}
+	else /* neighbor.c[d] is a solid cell */
+	  solid->s[d] = 0.;
+      }
+  }
+}
+
+/**
+ * gfs_init_solid_fractions_leaves:
+ * @domain: a #GfsDomain.
+ * @i: a list of #GfsSolids.
+ * @status: a temporary variable or %NULL.
+ *
+ * Initializes the solid fractions of the leaf cells of @domain.
+ *
+ * Returns: the number of thin cells.
+ */
+guint gfs_init_solid_fractions_leaves (GfsDomain * domain,
+				       GSList * i,
+				       GfsVariable * status)
+{
+  InitSolidParams p;
+
+  g_return_val_if_fail (domain != NULL, 0);
+
+  p.status = status ? status : gfs_temporary_variable (domain);
+  p.thin = 0;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, p.status);
+  while (i) {
+    gfs_domain_traverse_cut (domain, GFS_SOLID (i->data)->s, 
+			     FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+			     (FttCellTraverseCutFunc) set_solid_fractions_from_surface, &p);
+    i = i->next;
+  }
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) paint_mixed_leaf, p.status);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) match_fractions, p.status);
+  if (status == NULL)
+    gts_object_destroy (GTS_OBJECT (p.status));
+
+  return p.thin;
+}
+
+/**
+ * gfs_init_solid_fractions_from_children:
+ * @domain: a #GfsDomain.
+ * @destroy_solid: controls what to do with solid cells.
+ * @cleanup: a #FttCellCleanupFunc or %NULL.
+ * @data: user data to pass to @cleanup.
+ * @status: the status variable.
+ *
+ * Initializes the solid fractions of the non-leaf cells of @domain
+ * using the values of the leaf cells.
+ *
+ * If @destroy_solid is set to %TRUE, the cells entirely contained in
+ * the solid are destroyed using @cleanup as cleanup function.  
+ */
+void gfs_init_solid_fractions_from_children (GfsDomain * domain,
+					     gboolean destroy_solid,
+					     FttCellCleanupFunc cleanup,
+					     gpointer data,
+					     GfsVariable * status)
+{
+  InitSolidParams p;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (status != NULL);
+
+  p.destroy_solid = destroy_solid;
+  p.cleanup = cleanup;
+  p.data = data;
+  p.status = status;
+  p.solid_boxes = NULL;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) foreach_box, &p);
+  g_slist_foreach (p.solid_boxes, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (p.solid_boxes);
+}
+
+/**
+ * gfs_domain_init_solid_fractions:
+ * @domain: a #GfsDomain.
+ * @i: a list of #GfsSolids.
+ * @destroy_solid: controls what to do with solid cells.
+ * @cleanup: a #FttCellCleanupFunc or %NULL.
+ * @data: user data to pass to @cleanup.
+ * @status: a temporary variable or %NULL.
+ *
+ * Initializes the solid fractions of all the cells of @domain.
+ *
+ * If @destroy_solid is set to %TRUE, the cells entirely contained in
+ * the solid are destroyed using @cleanup as cleanup function.  
+ *
+ * Returns: the number of thin cells.
+ */
+guint gfs_domain_init_solid_fractions (GfsDomain * domain,
+				       GSList * i,
+				       gboolean destroy_solid,
+				       FttCellCleanupFunc cleanup,
+				       gpointer data,
+				       GfsVariable * status)
+{
+  GfsVariable * status1;
+
+  g_return_val_if_fail (domain != NULL, 0);
+
+  status1 = status ? status : gfs_temporary_variable (domain);
+  guint thin = gfs_init_solid_fractions_leaves (domain, i, status1);
+  gfs_init_solid_fractions_from_children (domain, destroy_solid, cleanup, data, status1);
+  if (status == NULL)
+    gts_object_destroy (GTS_OBJECT (status1));
+
+  return thin;
+}
+
+static gboolean check_area_fractions (const FttCell * root)
+{
+  guint i, level;
+  FttCellNeighbors neighbor;
+  gboolean ret = TRUE;
+  GfsSolidVector * solid;
+
+  level = ftt_cell_level (root);
+  ftt_cell_neighbors (root, &neighbor);
+  solid = GFS_STATE (root)->solid;
+
+  if (solid) {
+    GtsBBox bb;
+
+    ftt_cell_bbox (root, &bb);
+    if (!gts_bbox_point_is_inside (&bb, &solid->cm)) {
+      g_warning ("file %s: line %d (%s): cm (%g,%g,%g)/%d is not inside cell [(%g,%g,%g),(%g,%g,%g)]",
+		 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		 solid->cm.x, solid->cm.y, solid->cm.z, ftt_cell_level (root),
+		 bb.x1, bb.y1, bb.z1, 
+		 bb.x2, bb.y2, bb.z2);
+      ret = FALSE;
+      g_assert_not_reached ();
+    }
+    if (!gts_bbox_point_is_inside (&bb, &solid->ca)) {
+      g_warning ("file %s: line %d (%s): ca (%g,%g,%g)/%d is not inside cell [(%g,%g,%g),(%g,%g,%g)]",
+		 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		 solid->ca.x, solid->ca.y, solid->ca.z, ftt_cell_level (root),
+		 bb.x1, bb.y1, bb.z1, 
+		 bb.x2, bb.y2, bb.z2);
+      ret = FALSE;
+      g_assert_not_reached ();
+    }
+  }
+
+  for (i = 0; i < FTT_NEIGHBORS; i++)
+    if (neighbor.c[i]) {
+      GfsSolidVector * nsolid = GFS_STATE (neighbor.c[i])->solid;
+      FttDirection oi = FTT_OPPOSITE_DIRECTION (i);
+
+      if (ftt_cell_level (neighbor.c[i]) == level) {
+	if (GFS_IS_FLUID (root)) {
+	  if (!GFS_IS_FLUID (neighbor.c[i])) {
+	    if (1. - nsolid->s[oi] >= 1e-10) {
+	      FttVector p;
+	      ftt_cell_pos (root, &p);
+	      g_warning ("file %s: line %d (%s): (%g,%g,%g)/%d: s[%d]: %g",
+			 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+			 p.x, p.y, p.z, ftt_cell_level (root),
+			 oi, nsolid->s[oi]);
+	      ret = FALSE;
+	    }
+	    nsolid->s[oi] = 1.;
+	  }
+	}
+	else if (GFS_IS_MIXED (neighbor.c[i])) {
+	  if (fabs (solid->s[i] - nsolid->s[oi]) >= 1e-10) {
+	    FttVector p;
+	    ftt_cell_pos (root, &p);
+	    g_warning ("file %s: line %d (%s): (%g,%g,%g)/%d: s[%d]: %g neighbor->s[%d]: %g",
+		       __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		       p.x, p.y, p.z, ftt_cell_level (root),
+		       i, solid->s[i],
+		       oi, nsolid->s[oi]);
+	    ret = FALSE;
+	  }
+	  nsolid->s[oi] = solid->s[i];
+	}
+	else {
+	  if (1. - solid->s[i] >= 1e-10) {
+	    FttVector p;
+	    ftt_cell_pos (root, &p);
+	    g_warning ("file %s: line %d (%s): (%g,%g,%g)/%d: s[%d]: %g",
+		       __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		       p.x, p.y, p.z, ftt_cell_level (root),
+		       i, solid->s[i]);
+	    ret = FALSE;
+	  }
+	  solid->s[i] = 1.;
+	}
+      }
+      else { /* fine/coarse boundary */
+	g_assert (ftt_cell_level (neighbor.c[i]) == level - 1);
+	if (GFS_IS_FLUID (neighbor.c[i])) {
+	  if (GFS_IS_MIXED (root)) {
+	    if (1. - solid->s[i] >= 1e-10) {
+	      FttVector p;
+	      ftt_cell_pos (root, &p);
+	      g_warning ("file %s: line %d (%s): (%g,%g,%g)/%d: s[%d]: %g",
+			 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+			 p.x, p.y, p.z, ftt_cell_level (root),
+			 i, solid->s[i]);
+	      ret = FALSE;
+	    }
+	    solid->s[i] = 1.;
+	  }
+	}
+	else if (nsolid->s[oi] == 0.) {
+	  g_assert (GFS_IS_MIXED (root));
+	  if (solid->s[i] >= 1e-10) {
+	    FttVector p;
+	    ftt_cell_pos (root, &p);
+	    g_warning ("file %s: line %d (%s): (%g,%g,%g)/%d: s[%d]: %g",
+		       __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		       p.x, p.y, p.z, ftt_cell_level (root),
+		       i, solid->s[i]);
+	    ret = FALSE;
+	  }
+	  solid->s[i] = 0.;
+	}
+      }
+    }
+  
+  if (!FTT_CELL_IS_LEAF (root)) {
+    FttCellChildren child;
+
+    ftt_cell_children (root, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i] && !check_area_fractions (child.c[i]))
+	ret = FALSE;
+  }
+
+  return ret;
+}
+
+static void check_solid_fractions (FttCell * cell, gboolean * ret)
+{
+  FttCellChildren children;
+  guint n;
+
+  ftt_cell_children (cell, &children);
+  if (!GFS_IS_MIXED (cell)) {
+    for (n = 0; n < FTT_CELLS; n++)
+      if (children.c[n] && GFS_IS_MIXED (children.c[n])) {
+	g_warning ("file %s: line %d (%s): children[%d] is mixed (%g)"
+		   " parent is not",
+                   __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		   n, GFS_STATE (children.c[n])->solid->a);
+	*ret = FALSE;
+      }
+  }
+  else {
+    gdouble a = 0.;
+
+    for (n = 0; n < FTT_CELLS; n++)
+      if (children.c[n]) {
+	if (GFS_IS_MIXED (children.c[n]))
+	  a += GFS_STATE (children.c[n])->solid->a;
+	else
+	  a += 1.;
+      }
+    a /= FTT_CELLS;
+    if (fabs (GFS_STATE (cell)->solid->a - a) >= 1e-10) {
+      g_warning ("file %s: line %d (%s): children->a: %g parent->a: %g",
+		 __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,
+		 a, GFS_STATE (cell)->solid->a);
+	*ret = FALSE;
+    }
+  }
+}
+
+/**
+ * gfs_cell_check_solid_fractions:
+ * @root: the root #FttCell of the cell tree to check.
+ * 
+ * Checks the consistency of the solid fractions of each cell of the
+ * cell tree relative to the neighboring solid fractions.
+ *
+ * Returns: %TRUE if the solid fractions are consistent, %FALSE otherwise.
+ */
+gboolean gfs_cell_check_solid_fractions (FttCell * root)
+{
+  gboolean ret = TRUE;
+
+  g_return_val_if_fail (root != NULL, FALSE);
+
+  ftt_cell_traverse (root, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+		     (FttCellTraverseFunc) check_solid_fractions, &ret);
+  return ret & check_area_fractions (root);
+}
+
+static void save_solid (FttCell * cell, GfsVariable * c)
+{
+  GFS_DOUBLE_TO_POINTER (GFS_VARIABLE (cell, c->i)) = GFS_STATE (cell)->solid;
+  GFS_STATE (cell)->solid = NULL;
+}
+
+static void restore_solid (FttCell * cell, gpointer * data)
+{
+  GfsVariable * status = data[0];
+  GfsVariable * c = data[1];
+  GfsSolidVector * solid = GFS_STATE (cell)->solid;
+
+  GFS_STATE (cell)->solid = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, c));
+  if (solid) {
+    GFS_VALUE (cell, c) = solid->a;
+    g_free (solid);
+  }
+  else {
+    g_assert (GFS_VALUE (cell, status) == GFS_STATUS_SOLID || 
+	      GFS_VALUE (cell, status) == GFS_STATUS_FLUID);
+    GFS_VALUE (cell, c) = GFS_VALUE (cell, status) - 1.;
+  }
+}
+
+static void set_status (FttCell * cell, gpointer * data)
+{
+  GfsVariable * status = data[0];
+  gdouble * val = data[2];
+  GFS_VALUE (cell, status) = *val;
+}
+
+static void check_status (GfsBox * box, gpointer * data)
+{
+  GfsVariable * status = data[0];
+  if (!GFS_IS_MIXED (box->root) && GFS_VALUE (box->root, status) == GFS_STATUS_UNDEFINED) {
+    GfsGenericSurface * s = data[1];
+    FttVector pos;
+    ftt_cell_pos (box->root, &pos);
+    gdouble val = gfs_surface_point_is_inside (s, &pos) > 0 ?
+      GFS_STATUS_FLUID : GFS_STATUS_SOLID;
+    data[2] = &val;
+    ftt_cell_traverse (box->root, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+		       (FttCellTraverseFunc) set_status, data);
+  }
+}
+
+/**
+ * gfs_domain_init_fraction:
+ * @domain: a #GfsDomain.
+ * @s: a surface defining the interface boundary.
+ * @c: a #GfsVariable.
+ *
+ * Initializes the fraction @c of the interface @s contained in all
+ * the cells of @domain.
+ */
+void gfs_domain_init_fraction (GfsDomain * domain,
+			       GfsGenericSurface * s,
+			       GfsVariable * c)
+{
+  gpointer data[3];
+  GfsVariable * status;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (c != NULL);
+
+  status = gfs_temporary_variable (domain);
+
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) save_solid, c);
+  GfsSolid tmp;
+  tmp.s = s;
+  GSList * l = g_slist_prepend (NULL, &tmp);
+  gfs_domain_init_solid_fractions (domain, l, FALSE, NULL, NULL, status);
+  g_slist_free (l);
+  data[0] = status;
+  data[1] = s;
+  gts_container_foreach (GTS_CONTAINER (domain), (GtsFunc) check_status, data);
+  data[1] = c;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) restore_solid, data);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, c);
+
+  gts_object_destroy (GTS_OBJECT (status));
+}
+
+/**
+ * gfs_cell_cm:
+ * @cell: a #FttCell.
+ * @cm: a #FttVector.
+ *
+ * Fills @cm with the coordinates of the center of mass of @cell.
+ */
+void gfs_cell_cm (const FttCell * cell, FttVector * cm)
+{
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (cm != NULL);
+
+  if (GFS_IS_MIXED (cell))
+    *cm = GFS_STATE (cell)->solid->cm;
+  else
+    ftt_cell_pos (cell, cm);
+}
+
+/**
+ * gfs_solid_normal:
+ * @cell: a #FttCell.
+ * @n: a #FttVector.
+ *
+ * Fills @n with the components of the average unit normal to the
+ * fraction of solid boundary contained in @cell, multiplied by the
+ * area of the fraction of solid boundary contained in @cell.
+ */
+void gfs_solid_normal (const FttCell * cell, FttVector * n)
+{
+  GfsSolidVector * s;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (n != NULL);
+
+  if ((s = GFS_STATE (cell)->solid)) {
+    FttComponent c;
+
+#if (FTT_2D)
+    n->z = 0.;
+#endif /* 2D */
+
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&n->x)[c] = (s->s[2*c + 1] - s->s[2*c]);
+  }
+  else
+    n->x = n->y = n->z = 0.;
+}
+
+/**
+ * gfs_face_ca:
+ * @face: a #FttCellFace.
+ * @ca: a #FttVector.
+ *
+ * Fills @ca with the coordinates of the center of area of @face.
+ */
+void gfs_face_ca (const FttCellFace * face, FttVector * ca)
+{
+  gdouble f;
+
+  g_return_if_fail (face != NULL);
+  g_return_if_fail (ca != NULL);
+
+  ftt_face_pos (face, ca);
+  if ((f = GFS_FACE_FRACTION (face)) < 1.) {
+    GfsSolidVector * s = GFS_STATE (face->cell)->solid;
+    gdouble h = ftt_cell_size (face->cell);
+#if FTT_2D
+    FttComponent cp = FTT_ORTHOGONAL_COMPONENT (face->d/2);
+
+    (&ca->x)[cp] += (s->s[2*cp] > s->s[2*cp + 1]) ? (1. - f)/2.*h : (f - 1.)/2.*h;
+#else /* 3D */
+    static guint perpendicular[FTT_DIMENSION][2] = {
+      {FTT_Y, FTT_Z}, {FTT_Z, FTT_X}, {FTT_X, FTT_Y}
+    };
+    FttComponent c0 = face->d/2;
+    FttComponent c1 = perpendicular[c0][0];
+    FttComponent c2 = perpendicular[c0][1];
+    gboolean s1, s2;
+    FttVector m, p;
+    gdouble n, alpha;
+
+    m.x = s->s[2*c1 + 1] - s->s[2*c1];
+    m.y = s->s[2*c2 + 1] - s->s[2*c2];
+    s1 = (m.x < 0.);
+    s2 = (m.y < 0.);
+    m.x = fabs (m.x);
+    m.y = fabs (m.y);
+    n = m.x + m.y;
+    if (n > 0.) {
+      m.x /= n;
+      m.y /= n;
+      alpha = gfs_line_alpha (&m, f);
+      gfs_line_center (&m, alpha, f, &p);
+      if (s1) p.x = 1. - p.x;
+      if (s2) p.y = 1. - p.y;
+      (&ca->x)[c1] += (p.x - 0.5)*h;
+      (&ca->x)[c2] += (p.y - 0.5)*h;
+    }
+#endif /* 3D */
+  }
+}
+
+#if !FTT_2D
+static void outer_fractions_coarse_fine (FttCell * parent, FttDirection d)
+{
+  GfsSolidVector * solid = GFS_STATE (parent)->solid;
+  FttComponent c1 = d < 4 ? 2 : 0, c2 = d < 2 || d > 3 ? 1 : 0;
+  gdouble nm;
+  FttVector m;
+    
+  m.x = solid->s[2*c1 + 1] - solid->s[2*c1]; nm = fabs (m.x);
+  m.y = solid->s[2*c2 + 1] - solid->s[2*c2]; nm += fabs (m.y);
+  if (nm > 0.) {
+    m.x /= nm;
+    m.y /= nm;
+  }
+  else
+    m.x = 1.;
+  gdouble alpha = gfs_line_alpha (&m, solid->s[d]);
+  gdouble ss = 0.;
+    
+  FttCellChildren child;
+  guint i, n = ftt_cell_children_direction (parent, d, &child);
+  for (i = 0; i < n; i++)
+    if (child.c[i]) {
+      if (GFS_IS_MIXED (child.c[i])) {
+	GfsSolidVector * s = GFS_STATE (child.c[i])->solid;
+	gdouble alpha1 = alpha;
+	FttVector p;
+	
+	ftt_cell_relative_pos (child.c[i], &p);
+	alpha1 -= m.x*(0.25 + (&p.x)[c1]);
+	alpha1 -= m.y*(0.25 + (&p.x)[c2]);
+	
+	s->s[d] = gfs_line_area (&m, 2.*alpha1);
+	ss += s->s[d];
+      }
+      else
+	ss += 1.;
+    }
+  /* fixme: this should not happen 
+   * It happens in configurations where children cells are not cut by
+   * the VOF approximation but should have non-zero surface
+   * fractions */
+  if (fabs (solid->s[d] - ss/n) > 1e-5)
+    g_warning ("inconsistent surface fractions %d %f %f %f\n", d, solid->s[d], ss/n,
+	       fabs (solid->s[d] - ss/n));
+}
+#endif /* 3D */
+
+/**
+ * gfs_solid_coarse_fine:
+ * @parent: a mixed #FttCell with children.
+ * @domain: a #GfsDomain.
+ *
+ * Fills the solid properties of the children of @parent.
+ * Destroys all children entirely contained in the solid.
+ */
+void gfs_solid_coarse_fine (FttCell * parent, GfsDomain * domain)
+{
+#if FTT_2D3
+  g_assert_not_implemented ();
+#endif
+  g_return_if_fail (parent);
+  g_return_if_fail (domain);
+  g_return_if_fail (GFS_IS_MIXED (parent));
+  g_return_if_fail (!FTT_CELL_IS_LEAF (parent));
+
+  GfsSolidVector * solid = GFS_STATE (parent)->solid;
+  FttVector m;
+  FttComponent c;
+  gdouble n = 0;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    (&m.x)[c] = solid->s[2*c + 1] - solid->s[2*c];
+    n += fabs ((&m.x)[c]);
+  }
+  if (n > 0.)
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&m.x)[c] /= n;
+  else
+    m.x = 1.;
+  gdouble alpha = gfs_plane_alpha (&m, solid->a);
+
+  gdouble h = ftt_cell_size (parent)/2.;
+  guint level = ftt_cell_level (parent) + 1;
+  FttCellChildren child;
+  guint i;
+  ftt_cell_children (parent, &child);
+  for (i = 0; i < FTT_CELLS; i++) {
+    gdouble alpha1 = alpha;
+    FttVector p;
+
+    ftt_cell_relative_pos (child.c[i], &p);
+    for (c = 0; c < FTT_DIMENSION; c++)
+      alpha1 -= (&m.x)[c]*(0.25 + (&p.x)[c]);
+
+    if (GFS_STATE (child.c[i])->solid) {
+      g_free (GFS_STATE (child.c[i])->solid);
+      GFS_STATE (child.c[i])->solid = NULL;
+    }
+
+    gdouble a = gfs_plane_volume (&m, 2.*alpha1);
+    if (a > 0. && a < 1.) {
+      GfsSolidVector * s = GFS_STATE (child.c[i])->solid = g_malloc (sizeof (GfsSolidVector));
+      s->a = a;
+
+      ftt_cell_pos (child.c[i], &p);
+      gfs_plane_center (&m, 2.*alpha1, a, &s->cm);
+      gfs_plane_area_center (&m, 2.*alpha1, &s->ca);
+      for (c = 0; c < FTT_DIMENSION; c++) {
+	(&s->cm.x)[c] = (&p.x)[c] + h*((&s->cm.x)[c] - 0.5);
+	(&s->ca.x)[c] = (&p.x)[c] + h*((&s->ca.x)[c] - 0.5);
+      }
+
+      FttDirection d;
+      FttCellNeighbors n;
+      ftt_cell_neighbors (child.c[i], &n);
+      for (d = 0; d < FTT_NEIGHBORS; d++)
+	if (!n.c[d])
+	  s->s[d] = 0.;
+	else if (GFS_IS_MIXED (n.c[d]) && ftt_cell_level (n.c[d]) == level)
+	  s->s[d] = GFS_STATE (n.c[d])->solid->s[FTT_OPPOSITE_DIRECTION (d)];
+	else if (!ftt_cell_neighbor_is_brother (child.c[i], d) && GFS_IS_FLUID (n.c[d]))
+	  s->s[d] = 1.;
+	else {
+#if FTT_2D
+	  gdouble f;
+	  FttComponent c1 = d > 1, c2 = !c1;
+
+	  if ((&m.x)[c2] == 0.) f = 0.;
+	  else {
+	    f = (2.*alpha1 - (&m.x)[c1]*!(d % 2))/(&m.x)[c2];
+	    if (f < 0.) f = 0.; else if (f > 1.) f = 1.;
+	    if ((&m.x)[c2] < 0.)
+	      f = 1. - f;
+	  }
+	  s->s[d] = f;
+#else /* 3D */
+	  /* only initialises "inner" fractions */
+	  if (ftt_cell_neighbor_is_brother (child.c[i], d)) {
+	    FttComponent c1 = (d/2 + 1) % 3, c2 = (d/2 + 2) % 3;
+	    FttVector mp;
+	    mp.x = (&m.x)[c1]; 
+	    mp.y = (&m.x)[c2];
+	    s->s[d] = gfs_line_area (&mp, d % 2 ? 2.*alpha1 : 2.*alpha1 - (&m.x)[d/2]);
+	  }
+#endif /* 3D */
+	}
+    }
+    else if (a == 0.)
+      ftt_cell_destroy (child.c[i], (FttCellCleanupFunc) gfs_cell_cleanup, domain);
+  }
+
+#if !FTT_2D
+  FttCellNeighbors neighbor;
+  FttDirection d;
+  ftt_cell_neighbors (parent, &neighbor);
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (neighbor.c[d] && FTT_CELL_IS_LEAF (neighbor.c[d]) && !GFS_IS_FLUID (neighbor.c[d]))
+      outer_fractions_coarse_fine (parent, d);
+#endif /* 3D */
+}
+
+/* GfsSolid: Object */
+
+static void gfs_solid_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_solid_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  gfs_generic_surface_read (GFS_SOLID (*o)->s, gfs_object_simulation (*o), fp);
+}
+
+static void gfs_solid_write (GtsObject * o, FILE * fp)
+{
+  GfsSimulation * sim = gfs_object_simulation (o);
+  if (sim->output_solid) {
+    (* GTS_OBJECT_CLASS (gfs_solid_class ())->parent_class->write) (o, fp);
+    gfs_generic_surface_write (GFS_SOLID (o)->s, sim, fp);
+  }
+}
+
+static void gfs_solid_destroy (GtsObject * object)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_SOLID (object)->s));
+
+  (* GTS_OBJECT_CLASS (gfs_solid_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_solid_class_init (GtsObjectClass * klass)
+{
+  klass->read = gfs_solid_read;
+  klass->write = gfs_solid_write;
+  klass->destroy = gfs_solid_destroy;
+}
+
+static void gfs_solid_init (GfsSolid * object)
+{
+  object->s = GFS_GENERIC_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+  GFS_EVENT (object)->istep = G_MAXINT/2;
+}
+
+GfsEventClass * gfs_solid_class (void)
+{
+  static GfsEventClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_solid_info = {
+      "GfsSolid",
+      sizeof (GfsSolid),
+      sizeof (GfsEventClass),
+      (GtsObjectClassInitFunc) gfs_solid_class_init,
+      (GtsObjectInitFunc) gfs_solid_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_solid_info);
+  }
+
+  return klass;
+}
diff --git a/src/solid.h b/src/solid.h
new file mode 100644
index 0000000..6d47875
--- /dev/null
+++ b/src/solid.h
@@ -0,0 +1,95 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __SOLID_H__
+#define __SOLID_H__
+
+#include <gts.h>
+
+#include "domain.h"
+#include "event.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum {
+  GFS_STATUS_UNDEFINED = 0,
+  GFS_STATUS_SOLID     = 1,
+  GFS_STATUS_FLUID     = 2
+};
+
+void         gfs_cell_fluid                              (FttCell * cell);
+gboolean     gfs_solid_is_thin                           (FttCell * cell, 
+							  GfsGenericSurface * s);
+gboolean     gfs_set_2D_solid_fractions_from_surface     (FttCell * cell,
+							  GfsGenericSurface * s);
+guint        gfs_init_solid_fractions_leaves             (GfsDomain * domain,
+							  GSList * i,
+							  GfsVariable * status);
+void         gfs_init_solid_fractions_from_children      (GfsDomain * domain,
+							  gboolean destroy_solid,
+							  FttCellCleanupFunc cleanup,
+							  gpointer data,
+							  GfsVariable * status);
+guint        gfs_domain_init_solid_fractions             (GfsDomain * domain,
+							  GSList * i,
+							  gboolean destroy_solid,
+							  FttCellCleanupFunc cleanup,
+							  gpointer data,
+							  GfsVariable * status);
+void         gfs_cell_init_solid_fractions_from_children (FttCell * cell);
+gboolean     gfs_cell_check_solid_fractions              (FttCell * root);
+void         gfs_domain_init_fraction                    (GfsDomain * domain,
+							  GfsGenericSurface * s,
+							  GfsVariable * c);
+void         gfs_cell_cm                                 (const FttCell * cell, 
+							  FttVector * cm);
+void         gfs_solid_normal                            (const FttCell * cell,
+							  FttVector * n);
+void         gfs_face_ca                                 (const FttCellFace * face, 
+							  FttVector * ca);
+void         gfs_solid_coarse_fine                       (FttCell * parent,
+							  GfsDomain * domain);
+
+/* GfsSolid: Header */
+
+typedef struct _GfsSolid         GfsSolid;
+
+struct _GfsSolid {
+  /*< private >*/
+  GfsEvent parent;
+
+  /*< public >*/
+  GfsGenericSurface * s;
+};
+
+#define GFS_SOLID(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSolid,\
+					         gfs_solid_class ())
+#define GFS_IS_SOLID(obj)         (gts_object_is_from_class (obj,\
+						 gfs_solid_class ()))
+
+GfsEventClass * gfs_solid_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SOLID_H__ */
diff --git a/src/source.c b/src/source.c
new file mode 100644
index 0000000..358bbf3
--- /dev/null
+++ b/src/source.c
@@ -0,0 +1,1634 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include "source.h"
+#include "simulation.h"
+#include "solid.h"
+
+/**
+ * gfs_variable_mac_source:
+ * @v: a #GfsVariable.
+ * @cell: a #FttCell.
+ *
+ * Returns: the sum of all the sources for variable @v in @cell.
+ */
+gdouble gfs_variable_mac_source (GfsVariable * v, FttCell * cell)
+{
+  gdouble sum;
+  GSList * i;
+
+  g_return_val_if_fail (v != NULL, 0.);
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  if (v->sources == NULL)
+    return 0.;
+
+  sum = 0.;
+  i = GTS_SLIST_CONTAINER (v->sources)->items;
+  while (i) {
+    GfsSourceGeneric * s = i->data;
+
+    if (s->mac_value)
+      sum += (* s->mac_value) (s, cell, v);
+    i = i->next;
+  }
+  return sum;
+}
+
+typedef struct {
+  GfsVariable * v, * sv;
+  gdouble dt;
+} SourcePar;
+
+static void add_sources (FttCell * cell, SourcePar * p)
+{
+  GSList * i = GTS_SLIST_CONTAINER (p->v->sources)->items;
+  gdouble sum = 0;
+  
+  while (i) {
+    GfsSourceGeneric * s = i->data;
+
+    if (s->centered_value)
+      sum += (* s->centered_value) (s, cell, p->v);
+    i = i->next;
+  }
+  GFS_VALUE (cell, p->sv) += p->dt*sum;
+}
+
+/**
+ * gfs_domain_variable_centered_sources:
+ * @domain: a #GfsDomain.
+ * @v: a #GfsVariable.
+ * @sv: a #GfsVariable.
+ * @dt: the timestep.
+ *
+ * Adds the source terms for @v to @sv.
+ */
+void gfs_domain_variable_centered_sources (GfsDomain * domain, 
+					   GfsVariable * v,
+					   GfsVariable * sv,
+					   gdouble dt)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (sv != NULL);
+
+  if (v->sources) {
+    SourcePar p;
+    p.v = v;
+    p.sv = sv;
+    p.dt = dt;
+    gfs_domain_cell_traverse (domain, 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) add_sources, &p);
+  }
+}
+
+/**
+ * gfs_domain_variable_fluxes:
+ * @domain: a #GfsDomain.
+ * @v: a #GfsVariable.
+ * @dt: the timestep.
+ *
+ * Returns: a new temporary variable containing the fluxes or %NULL.
+ */
+GfsVariable * gfs_domain_variable_fluxes (GfsDomain * domain,
+					  GfsVariable * v,
+					  gdouble dt)
+{
+  GfsVariable * sv = NULL;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+  g_return_val_if_fail (v != NULL, NULL);
+
+  if (!v->sources)
+    return NULL;
+
+  GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+  while (i) {
+    if (GFS_SOURCE_GENERIC (i->data)->flux) {
+      if (sv == NULL) {
+	sv = gfs_temporary_variable (domain);
+	gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) gfs_cell_reset, sv);
+      }
+      (* GFS_SOURCE_GENERIC (i->data)->flux) (i->data, domain, v, sv, dt);
+    }
+    i = i->next;
+  }
+  return sv;
+}
+
+/* GfsSourceGeneric: Object */
+
+static void source_generic_init (GfsSourceGeneric * s)
+{
+  GFS_EVENT (s)->istep = 1;
+}
+
+GfsSourceGenericClass * gfs_source_generic_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_generic_info = {
+      "GfsSourceGeneric",
+      sizeof (GfsSourceGeneric),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) source_generic_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &gfs_source_generic_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_source_find:
+ * @v: a #GfsVariable.
+ * @klass: a #GfsSourceGenericClass.
+ *
+ * Returns: the first source of @v descendant of @klass, or %NULL if
+ * none was found.
+ */
+GfsSourceGeneric * gfs_source_find (GfsVariable * v, GfsSourceGenericClass * klass)
+{
+  g_return_val_if_fail (v != NULL, NULL);
+  g_return_val_if_fail (klass != NULL, NULL);
+
+  if (v->sources) {
+    GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+    
+    while (i) {
+      GtsObject * o = i->data;
+      
+      if (gts_object_is_from_class (o, klass))
+        return GFS_SOURCE_GENERIC (o);
+      i = i->next;
+    }
+  }
+  return NULL;
+}
+
+/* GfsSourceScalar: Object */
+
+static void source_scalar_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_source_scalar_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_source_scalar_class ())->parent_class->write) 
+      (o, fp);
+
+  g_assert (GFS_SOURCE_SCALAR (o)->v);
+  fprintf (fp, " %s", GFS_SOURCE_SCALAR (o)->v->name);
+}
+
+static void source_scalar_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceScalar * source;
+  GfsDomain * domain;
+
+  if (GTS_OBJECT_CLASS (gfs_source_scalar_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_scalar_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  source = GFS_SOURCE_SCALAR (*o);
+  domain =  GFS_DOMAIN (gfs_object_simulation (source));
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsVariable)");
+    return;
+  }
+  source->v = gfs_variable_from_name (domain->variables, 
+				      fp->token->str);
+  if (source->v == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  if (source->v->sources == NULL)
+    source->v->sources = 
+      gts_container_new (GTS_CONTAINER_CLASS (gts_slist_container_class ()));
+  gts_container_add (source->v->sources, GTS_CONTAINEE (source));
+  
+  gts_file_next_token (fp);
+}
+
+static void source_scalar_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read =  source_scalar_read;
+  GTS_OBJECT_CLASS (klass)->write = source_scalar_write;
+}
+
+GfsSourceGenericClass * gfs_source_scalar_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_scalar_info = {
+      "GfsSourceScalar",
+      sizeof (GfsSourceScalar),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_scalar_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_generic_class ()),
+				  &gfs_source_scalar_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceVelocity: Object */
+
+static void source_velocity_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceVelocity * source;
+  GfsDomain * domain;
+  FttComponent c;
+
+  if (GTS_OBJECT_CLASS (gfs_source_velocity_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_velocity_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  source = GFS_SOURCE_VELOCITY (*o);
+  domain =  GFS_DOMAIN (gfs_object_simulation (source));
+  if (!(source->v = gfs_domain_velocity (domain))) {
+    gts_file_error (fp, "cannot find velocity components");
+    return;
+  }
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    if (source->v[c]->sources == NULL)
+      source->v[c]->sources = 
+	gts_container_new (GTS_CONTAINER_CLASS (gts_slist_container_class ()));
+    gts_container_add (source->v[c]->sources, GTS_CONTAINEE (source));
+  }
+}
+
+static void source_velocity_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read =  source_velocity_read;
+}
+
+GfsSourceGenericClass * gfs_source_velocity_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_info = {
+      "GfsSourceGeneric",
+      sizeof (GfsSourceVelocity),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_velocity_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_generic_class ()),
+				  &source_info);
+  }
+
+  return klass;
+}
+
+/* GfsSource: Object */
+
+static void source_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE (o)->intensity)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE (o)->intensity));
+
+  (* GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->destroy) (o);
+}
+
+static gdouble source_face_value (GfsSourceGeneric * s, 
+				  FttCellFace * face, 
+				  GfsVariable * v)
+{
+  return gfs_function_face_value (GFS_SOURCE (s)->intensity, face);
+}
+
+static void source_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_SOURCE (*o)->intensity = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_set_units (GFS_SOURCE (*o)->intensity, GFS_SOURCE_SCALAR (*o)->v->units);
+  gfs_function_read (GFS_SOURCE (*o)->intensity, gfs_object_simulation (*o), fp);
+  if (fp->type != GTS_ERROR) {
+    GfsSourceGeneric * s = GFS_SOURCE_GENERIC (*o);
+    gchar * name = GFS_SOURCE_SCALAR (s)->v->name;
+    if (!strcmp (name, "U") || !strcmp (name, "V") || !strcmp (name, "W")) {
+      s->mac_value = s->centered_value = NULL;
+      s->face_value = source_face_value;
+    }
+  }
+}
+
+static void source_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->write) 
+      (o, fp);
+  gfs_function_write (GFS_SOURCE (o)->intensity, fp);
+}
+
+static void source_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = source_destroy;
+  GTS_OBJECT_CLASS (klass)->read = source_read;
+  GTS_OBJECT_CLASS (klass)->write = source_write;
+}
+
+static gdouble source_value (GfsSourceGeneric * s, 
+			     FttCell * cell, 
+			     GfsVariable * v)
+{
+  return gfs_function_value (GFS_SOURCE (s)->intensity, cell);
+}
+
+static void source_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = source_value;
+}
+
+GfsSourceGenericClass * gfs_source_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_info = {
+      "GfsSource",
+      sizeof (GfsSource),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_class_init,
+      (GtsObjectInitFunc) source_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_scalar_class ()),
+				  &source_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceControl: Object */
+
+static void source_control_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE_CONTROL (o)->intensity)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_CONTROL (o)->intensity));
+
+  (* GTS_OBJECT_CLASS (gfs_source_control_class ())->parent_class->destroy) (o);
+}
+
+static void source_control_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_control_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_SOURCE_CONTROL (*o)->intensity = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_set_units (GFS_SOURCE_CONTROL (*o)->intensity, GFS_SOURCE_SCALAR (*o)->v->units);
+  gfs_function_read (GFS_SOURCE_CONTROL (*o)->intensity, gfs_object_simulation (*o), fp);
+}
+
+static void source_control_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_control_class ())->parent_class->write) (o, fp);
+  gfs_function_write (GFS_SOURCE_CONTROL (o)->intensity, fp);
+}
+
+typedef struct {
+  GfsVariable * v;
+  gdouble s, sv;
+} Sum;
+
+static void sum (FttCell * cell, Sum * s)
+{
+  gdouble vol = gfs_cell_volume (cell, s->v->domain);
+  s->s += vol*GFS_VALUE (cell, s->v);
+  s->sv += vol;
+}
+
+static gboolean source_control_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* gfs_event_class ()->event) (event, sim)) {
+    GfsSourceControl * s = GFS_SOURCE_CONTROL (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    Sum su = { GFS_SOURCE_SCALAR (event)->v, 0., 0. };
+    gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) sum, &su);
+    gfs_all_reduce (domain, su.s, MPI_DOUBLE, MPI_SUM);
+    gfs_all_reduce (domain, su.sv, MPI_DOUBLE, MPI_SUM);
+    s->s = sim->advection_params.dt > 0. && su.sv > 0. ? 
+      (gfs_function_value (s->intensity, NULL) - su.s/su.sv)/sim->advection_params.dt: 0.;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void source_control_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = source_control_read;
+  GTS_OBJECT_CLASS (klass)->write = source_control_write;
+  GTS_OBJECT_CLASS (klass)->destroy = source_control_destroy;
+  GFS_EVENT_CLASS (klass)->event = source_control_event;
+}
+
+static gdouble source_control_value (GfsSourceGeneric * s, 
+				     FttCell * cell, 
+				     GfsVariable * v)
+{
+  return GFS_SOURCE_CONTROL (s)->s;
+}
+
+static void source_control_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = source_control_value;
+}
+
+GfsSourceGenericClass * gfs_source_control_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_control_info = {
+      "GfsSourceControl",
+      sizeof (GfsSourceControl),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_control_class_init,
+      (GtsObjectInitFunc) source_control_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_scalar_class ()),
+				  &source_control_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceControlField: Object */
+
+static void source_control_field_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE_CONTROL_FIELD (o)->s)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_CONTROL_FIELD (o)->s));
+
+  (* GTS_OBJECT_CLASS (gfs_source_control_field_class ())->parent_class->destroy) (o);
+}
+
+static void source_control_field_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_control_field_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting an integer (level)");
+    return;
+  }
+  GFS_SOURCE_CONTROL_FIELD (*o)->level = atoi (fp->token->str);
+  gts_file_next_token (fp);
+
+  GFS_SOURCE_CONTROL_FIELD (*o)->s = 
+    gfs_temporary_variable (GFS_DOMAIN (gfs_object_simulation (*o)));
+}
+
+static void source_control_field_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_control_field_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %d", GFS_SOURCE_CONTROL_FIELD (o)->level);
+}
+
+static void set_s (FttCell * cell, GfsSourceControlField * f)
+{
+  GFS_VALUE (cell, f->s) = GFS_SOURCE_CONTROL (f)->s;
+}
+
+static void source_control_field_root (FttCell * root, GfsSourceControlField * f)
+{
+  Sum su = { GFS_SOURCE_SCALAR (f)->v, 0., 0. };
+  ftt_cell_traverse (root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		     (FttCellTraverseFunc) sum, &su);
+  gdouble dt = gfs_object_simulation (f)->advection_params.dt;
+  GFS_SOURCE_CONTROL (f)->s = dt > 0. && su.sv > 0. ? 
+    (gfs_function_value (GFS_SOURCE_CONTROL (f)->intensity, root) - su.s/su.sv)/dt: 0.;
+  ftt_cell_traverse (root, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		     (FttCellTraverseFunc) set_s, f);
+}
+
+static gboolean source_control_field_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* gfs_event_class ()->event) (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, 
+			      FTT_TRAVERSE_LEVEL | FTT_TRAVERSE_LEAFS, 
+			      GFS_SOURCE_CONTROL_FIELD (event)->level,
+			      (FttCellTraverseFunc) source_control_field_root, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void source_control_field_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = source_control_field_destroy;
+  GTS_OBJECT_CLASS (klass)->read = source_control_field_read;
+  GTS_OBJECT_CLASS (klass)->write = source_control_field_write;
+  GFS_EVENT_CLASS (klass)->event = source_control_field_event;
+}
+
+static gdouble source_control_field_value (GfsSourceGeneric * s, 
+					   FttCell * cell, 
+					   GfsVariable * v)
+{
+  return GFS_VALUE (cell, GFS_SOURCE_CONTROL_FIELD (s)->s);
+}
+
+static void source_control_field_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = source_control_field_value;
+}
+
+GfsSourceGenericClass * gfs_source_control_field_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_control_field_info = {
+      "GfsSourceControlField",
+      sizeof (GfsSourceControlField),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_control_field_class_init,
+      (GtsObjectInitFunc) source_control_field_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_control_class ()),
+				  &source_control_field_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceFlux: Object */
+
+static void source_flux_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE_FLUX (o)->intensity)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_FLUX (o)->intensity));
+  if (GFS_SOURCE_FLUX (o)->fraction)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_FLUX (o)->fraction));
+
+  (* GTS_OBJECT_CLASS (gfs_source_flux_class ())->parent_class->destroy) (o);
+}
+
+static void source_flux_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_flux_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsSourceFlux * f = GFS_SOURCE_FLUX (*o);
+  f->intensity = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_set_units (f->intensity, GFS_SOURCE_SCALAR (f)->v->units + FTT_DIMENSION);
+  gfs_function_read (f->intensity, gfs_object_simulation (f), fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  f->fraction = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_read (f->fraction, gfs_object_simulation (f), fp);
+}
+
+static void source_flux_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_flux_class ())->parent_class->write) (o, fp);
+  gfs_function_write (GFS_SOURCE_FLUX (o)->intensity, fp);
+  gfs_function_write (GFS_SOURCE_FLUX (o)->fraction, fp);
+}
+
+static void add (FttCell * cell, GfsSourceFlux * s)
+{
+  s->s += gfs_cell_volume (cell, GFS_DOMAIN (gfs_object_simulation (s)))*
+    gfs_function_value (s->fraction, cell);
+}
+
+static gboolean source_flux_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* gfs_event_class ()->event) (event, sim)) {
+    GfsSourceFlux * s = GFS_SOURCE_FLUX (event);
+    s->s = 0.;
+    gfs_domain_traverse_leaves (GFS_DOMAIN (sim), (FttCellTraverseFunc) add, s);
+    s->s = s->s > 0. ? gfs_function_value (s->intensity, NULL)/s->s : 0.;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void source_flux_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = source_flux_read;
+  GTS_OBJECT_CLASS (klass)->write = source_flux_write;
+  GTS_OBJECT_CLASS (klass)->destroy = source_flux_destroy;
+  GFS_EVENT_CLASS (klass)->event = source_flux_event;
+}
+
+static gdouble source_flux_value (GfsSourceGeneric * s, 
+				  FttCell * cell, 
+				  GfsVariable * v)
+{
+  return GFS_SOURCE_FLUX (s)->s*gfs_function_value (GFS_SOURCE_FLUX (s)->fraction, cell);
+}
+
+static void source_flux_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = source_flux_value;
+}
+
+GfsSourceGenericClass * gfs_source_flux_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_flux_info = {
+      "GfsSourceFlux",
+      sizeof (GfsSourceFlux),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_flux_class_init,
+      (GtsObjectInitFunc) source_flux_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_scalar_class ()),
+				  &source_flux_info);
+  }
+
+  return klass;
+}
+
+/* GfsDiffusion: Object */
+
+static void diffusion_destroy (GtsObject * o)
+{
+  GfsDiffusion * d = GFS_DIFFUSION (o);
+
+  if (d->mu && d->mu != gfs_function_get_variable (d->val))
+    gts_object_destroy (GTS_OBJECT (d->mu));
+  gts_object_destroy (GTS_OBJECT (d->val));
+
+  (* GTS_OBJECT_CLASS (gfs_diffusion_class ())->parent_class->destroy) (o);
+}
+
+static void diffusion_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDiffusion * d = GFS_DIFFUSION (*o);
+
+  gfs_function_read (d->val, gfs_object_simulation (*o), fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  gfs_function_set_units (d->val, 2.);
+
+  if (fp->type == '{') {
+    gfs_multilevel_params_read (&d->par, fp);
+    if (fp->type == GTS_ERROR)
+    return;
+  }
+}
+
+static void diffusion_write (GtsObject * o, FILE * fp)
+{
+  gfs_function_write (GFS_DIFFUSION (o)->val, fp);
+  fputc (' ', fp);
+  gfs_multilevel_params_write (&GFS_DIFFUSION (o)->par, fp);
+}
+
+static void update_mu (FttCell * cell, GfsDiffusion * d)
+{
+  GFS_VARIABLE (cell, d->mu->i) = gfs_function_value (d->val, cell);
+}
+
+static gboolean diffusion_event (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsDiffusion * d = GFS_DIFFUSION (event);
+
+  if (gfs_function_get_constant_value (d->val) == G_MAXDOUBLE) {
+    if (d->mu == NULL && (d->mu = gfs_function_get_variable (d->val)) == NULL)
+      d->mu = gfs_temporary_variable (GFS_DOMAIN (sim));
+    if (d->mu != gfs_function_get_variable (d->val))
+      gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) update_mu, event);
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_get_from_below_intensive, d->mu);
+    gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_ALL, -1, d->mu);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gdouble diffusion_face (GfsDiffusion * d, FttCellFace * f)
+{
+  if (d->mu) return gfs_face_interpolated_value (f, d->mu->i);
+  gdouble val = gfs_function_get_constant_value (d->val);
+  return val < G_MAXDOUBLE ? val : 0.;
+}
+
+static gdouble diffusion_cell (GfsDiffusion * d, FttCell * cell)
+{
+  if (d->mu) return GFS_VARIABLE (cell, d->mu->i);
+  gdouble val = gfs_function_get_constant_value (d->val);
+  return val < G_MAXDOUBLE ? val : 0.;
+}
+
+static void diffusion_class_init (GfsDiffusionClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = diffusion_destroy;
+  GTS_OBJECT_CLASS (klass)->read = diffusion_read;
+  GTS_OBJECT_CLASS (klass)->write = diffusion_write;
+  GFS_EVENT_CLASS (klass)->event = diffusion_event;
+  klass->face = diffusion_face;
+  klass->cell = diffusion_cell;
+}
+
+static void diffusion_init (GfsDiffusion * d)
+{
+  gfs_multilevel_params_init (&d->par);
+  d->par.tolerance = 1e-6;
+  d->val = gfs_function_new (gfs_function_class (), 0.);
+  d->mu = NULL;
+}
+
+GfsDiffusionClass * gfs_diffusion_class (void)
+{
+  static GfsDiffusionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo diffusion_info = {
+      "GfsDiffusion",
+      sizeof (GfsDiffusion),
+      sizeof (GfsDiffusionClass),
+      (GtsObjectClassInitFunc) diffusion_class_init,
+      (GtsObjectInitFunc) diffusion_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()),
+				  &diffusion_info);
+  }
+
+  return klass;
+}
+
+gdouble gfs_diffusion_face (GfsDiffusion * d, FttCellFace * f)
+{
+  return (* GFS_DIFFUSION_CLASS (GTS_OBJECT (d)->klass)->face) (d, f);
+}
+
+gdouble gfs_diffusion_cell (GfsDiffusion * d, FttCell * cell)
+{
+  return (* GFS_DIFFUSION_CLASS (GTS_OBJECT (d)->klass)->cell) (d, cell);
+}
+
+/* GfsSourceDiffusion: Object */
+
+static void source_diffusion_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_SOURCE_DIFFUSION (o)->D));
+
+  (* GTS_OBJECT_CLASS (gfs_source_diffusion_class ())->parent_class->destroy) (o);
+}
+
+static GfsSourceDiffusion * previous_diffusion_source (GfsVariable * v,
+						       GfsSourceDiffusion * d)
+{
+  GSList * i;
+
+  i = GTS_SLIST_CONTAINER (v->sources)->items;
+  while (i) {
+    if (i->data != d && GFS_IS_SOURCE_DIFFUSION (i->data))
+      return i->data;
+    i = i->next;
+  }
+  return NULL;
+}
+
+static void source_diffusion_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceDiffusion * d;
+
+  if (GTS_OBJECT_CLASS (gfs_source_diffusion_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_diffusion_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  d = GFS_SOURCE_DIFFUSION (*o);
+  if (previous_diffusion_source (GFS_SOURCE_SCALAR (d)->v, d)) {
+    gts_file_error (fp, "only one diffusion source can be specified");
+    return;
+  }
+
+  gfs_object_simulation_set (d->D, gfs_object_simulation (d));
+  (* GTS_OBJECT (d->D)->klass->read) ((GtsObject **) &d->D, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (GFS_SOURCE_SCALAR (d)->v->component < FTT_DIMENSION &&
+      gfs_function_get_constant_value (d->D->val) == G_MAXDOUBLE)
+      g_warning ("%d:%d: Terms may be missing when using variable diffusion\n"
+		 "on vector quantities",
+		 fp->line, fp->pos);
+}
+
+static void source_diffusion_write (GtsObject * o, FILE * fp)
+{
+  GfsSourceDiffusion * d = GFS_SOURCE_DIFFUSION (o);
+
+  (* GTS_OBJECT_CLASS (gfs_source_diffusion_class ())->parent_class->write) (o, fp);
+  (* GTS_OBJECT (d->D)->klass->write) (GTS_OBJECT (d->D), fp);
+}
+
+static gboolean source_diffusion_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* gfs_event_class ()->event) (event, sim)) {
+    GfsSourceDiffusion * d = GFS_SOURCE_DIFFUSION (event);
+
+    if ((* GFS_EVENT_CLASS (GTS_OBJECT (d->D)->klass)->event))
+      (* GFS_EVENT_CLASS (GTS_OBJECT (d->D)->klass)->event) (GFS_EVENT (d->D), sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gdouble source_diffusion_value (GfsSourceGeneric * s, 
+				       FttCell * cell,
+				       GfsVariable * v)
+{
+  FttCellFace f;
+  FttCellNeighbors n;
+  GfsGradient g = { 0., 0. };
+  gdouble v0, h;
+
+  if (GFS_IS_MIXED (cell)) /* this improves results for channel test */
+    return 0.;
+
+  v0 = GFS_VARIABLE (cell, v->i);
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &n);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    gdouble D;
+
+    f.neighbor = n.c[f.d];
+    D = gfs_source_diffusion_face (GFS_SOURCE_DIFFUSION (s), &f);
+    if (f.neighbor) {
+      GfsGradient e;
+
+      gfs_face_gradient (&f, &e, v->i, -1);
+      g.a += D*e.a;
+      g.b += D*e.b;
+    }
+    else if (f.d/2 == v->component) {
+      g.a += D;
+      g.b -= D*v0;
+    }
+  }
+  h = ftt_cell_size (cell);
+
+  GfsFunction * alpha = v->component < FTT_DIMENSION ? 
+    gfs_object_simulation (s)->physical_params.alpha : NULL;
+  return (alpha ? gfs_function_value (alpha, cell) : 1.)*(g.b - g.a*v0)/(h*h);
+}
+
+static void source_diffusion_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = source_diffusion_destroy;
+  GTS_OBJECT_CLASS (klass)->read = source_diffusion_read;
+  GTS_OBJECT_CLASS (klass)->write = source_diffusion_write;
+
+  GFS_EVENT_CLASS (klass)->event = source_diffusion_event;
+}
+
+static void source_diffusion_init (GfsSourceDiffusion * d)
+{
+  d->D = GFS_DIFFUSION (gts_object_new (GTS_OBJECT_CLASS (gfs_diffusion_class ())));
+  GFS_SOURCE_GENERIC (d)->mac_value = source_diffusion_value;
+}
+
+GfsSourceGenericClass * gfs_source_diffusion_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_diffusion_info = {
+      "GfsSourceDiffusion",
+      sizeof (GfsSourceDiffusion),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_diffusion_class_init,
+      (GtsObjectInitFunc) source_diffusion_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_scalar_class ()),
+				  &source_diffusion_info);
+  }
+
+  return klass;
+}
+
+gdouble gfs_source_diffusion_face (GfsSourceDiffusion * d, FttCellFace * f)
+{
+  g_return_val_if_fail (d != NULL, 0.);
+  g_return_val_if_fail (f != NULL, 0.);
+
+  return gfs_diffusion_face (d->D, f);
+}
+
+gdouble gfs_source_diffusion_cell (GfsSourceDiffusion * d, FttCell * cell)
+{
+  g_return_val_if_fail (d != NULL, 0.);
+  g_return_val_if_fail (cell != NULL, 0.);
+
+  return gfs_diffusion_cell (d->D, cell);
+}
+
+/* GfsSourceDiffusionExplicit: Object */
+
+static void explicit_diffusion (FttCell * cell, GfsSourceGeneric * s)
+{
+  GFS_VARIABLE (cell, GFS_SOURCE_DIFFUSION_EXPLICIT (s)->s->i) = 
+    source_diffusion_value (s, cell, GFS_SOURCE_SCALAR (s)->v);
+}
+
+static gboolean gfs_source_diffusion_explicit_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_source_diffusion_explicit_class ())->parent_class)->event) (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) explicit_diffusion, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_source_diffusion_explicit_read (GtsObject ** o, GtsFile * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_source_diffusion_explicit_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_source_diffusion_explicit_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GFS_SOURCE_DIFFUSION_EXPLICIT (*o)->s = 
+    gfs_temporary_variable (GFS_DOMAIN (gfs_object_simulation (*o)));
+}
+
+static void gfs_source_diffusion_explicit_destroy (GtsObject * o)
+{
+  if (GFS_SOURCE_DIFFUSION_EXPLICIT (o)->s)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_DIFFUSION_EXPLICIT (o)->s));
+
+  (* GTS_OBJECT_CLASS (gfs_source_diffusion_explicit_class ())->parent_class->destroy) (o);
+}
+
+static gdouble source_diffusion_explicit_value (GfsSourceGeneric * s, 
+					     FttCell * cell,
+					     GfsVariable * v)
+{
+  return GFS_VARIABLE (cell, GFS_SOURCE_DIFFUSION_EXPLICIT (s)->s->i);
+}
+
+typedef struct {
+  GfsFunction * alpha;
+  GfsSourceGeneric * s;
+  gdouble dtmax;
+} StabilityParams;
+
+static void cell_diffusion_stability (FttCell * cell,
+				      StabilityParams * par)
+{
+  if (GFS_IS_MIXED (cell))
+    return;
+
+  FttCellFace f;
+  FttCellNeighbors n;
+  gdouble Dmax = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &n);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    gdouble D;
+
+    f.neighbor = n.c[f.d];
+    D = gfs_source_diffusion_face (GFS_SOURCE_DIFFUSION (par->s), &f);
+    if (D > Dmax)
+      Dmax = D;
+  }
+
+  gdouble h = ftt_cell_size (cell);
+  if (Dmax > 0.) {
+    gdouble dtmax = h*h/(Dmax*(par->alpha ? gfs_function_value (par->alpha, cell) : 1.));
+    if (dtmax < par->dtmax)
+      par->dtmax = dtmax;
+  }
+}
+
+static gdouble source_diffusion_stability (GfsSourceGeneric * s,
+					   GfsSimulation * sim)
+{
+  StabilityParams par;
+
+  par.s = s;
+  par.dtmax = G_MAXDOUBLE;
+  par.alpha = NULL;
+  gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) cell_diffusion_stability, &par);
+  return par.dtmax;
+}
+
+static void gfs_source_diffusion_explicit_class_init (GfsSourceGenericClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_source_diffusion_explicit_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_source_diffusion_explicit_read;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_source_diffusion_explicit_destroy;
+  klass->stability = source_diffusion_stability;
+}
+
+static void gfs_source_diffusion_explicit_init (GfsSourceGeneric * s)
+{
+  s->mac_value = s->centered_value = source_diffusion_explicit_value;
+}
+
+GfsSourceGenericClass * gfs_source_diffusion_explicit_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_diffusion_explicit_info = {
+      "GfsSourceDiffusionExplicit",
+      sizeof (GfsSourceDiffusionExplicit),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_diffusion_explicit_class_init,
+      (GtsObjectInitFunc) gfs_source_diffusion_explicit_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_diffusion_class ()),
+				  &gfs_source_diffusion_explicit_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceViscosity: Object */
+
+typedef struct {
+  GfsSourceGeneric * s;
+  GfsVariable * v, * sv, * tv;
+  gdouble dt;
+} FluxPar;
+
+static void add_viscosity_transverse_flux (FttCell * cell, FluxPar * p)
+{
+  FttCellFace f;
+  FttCellNeighbors n;
+  gdouble transverse = 0.;
+
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &n);
+#if FTT_2D
+  FttComponent ortho = (p->v->component + 1) % FTT_DIMENSION;
+
+  for (f.d = 2*ortho; f.d <= 2*ortho + 1; f.d++) {
+    f.neighbor = n.c[f.d];
+    transverse += (FTT_FACE_DIRECT (&f) ? 1. : -1.)*
+      gfs_face_weighted_interpolated_value (&f, p->tv->i);
+  }
+#else
+  g_assert_not_implemented ();
+#endif  
+
+  GfsFunction * alpha = gfs_object_simulation (p->s)->physical_params.alpha;
+  gdouble h = ftt_cell_size (cell);
+  GFS_VALUE (cell, p->sv) += (alpha ? gfs_function_value (alpha, cell) : 1.)*transverse/h;
+}
+
+static void compute_transverse (FttCell * cell, FluxPar * p)
+{
+  GfsVariable ** v = GFS_SOURCE_VISCOSITY (p->s)->v;
+  gdouble h = ftt_cell_size (cell);
+  GFS_VALUE (cell, p->tv) = gfs_center_gradient (cell, 
+						 p->v->component, 
+						 v[(p->v->component + 1) % FTT_DIMENSION]->i)/h;
+}
+
+static void source_viscosity_transverse_flux (GfsSourceGeneric * s, 
+					      GfsDomain * domain, 
+					      GfsVariable * v, GfsVariable * sv, 
+					      gdouble dt)
+{
+  FluxPar p;
+
+  gfs_diffusion_coefficients (domain, GFS_SOURCE_DIFFUSION (s), dt, NULL, NULL, NULL, 1.);
+  p.s = s;
+  p.v = v;
+  p.sv = sv;
+  p.dt = dt;
+  p.tv = gfs_temporary_variable (domain);
+  gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		       (FttCellTraverseFunc) compute_transverse, &p,
+		       p.tv, p.tv);
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) add_viscosity_transverse_flux, &p);
+  gts_object_destroy (GTS_OBJECT (p.tv));
+}
+
+static void source_viscosity_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceViscosity * source;
+  GfsSourceDiffusion * d;
+  GfsDomain * domain;
+  FttComponent c;
+
+  (* GTS_OBJECT_CLASS (gfs_source_velocity_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  source = GFS_SOURCE_VISCOSITY (*o);
+  domain =  GFS_DOMAIN (gfs_object_simulation (source));
+  if (GFS_IS_AXI (domain) && !GFS_IS_SOURCE_VISCOSITY_EXPLICIT (source)) {
+    GfsSourceGeneric * s = GFS_SOURCE_GENERIC (source);
+    s->mac_value = NULL;
+    s->centered_value = NULL;
+    s->flux = source_viscosity_transverse_flux;
+  }
+  if (!(source->v = gfs_domain_velocity (domain))) {
+    gts_file_error (fp, "cannot find velocity components");
+    return;
+  }
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    if (source->v[c]->sources == NULL)
+      source->v[c]->sources = 
+	gts_container_new (GTS_CONTAINER_CLASS (gts_slist_container_class ()));
+    gts_container_add (source->v[c]->sources, GTS_CONTAINEE (source));
+  }
+
+  d = GFS_SOURCE_DIFFUSION (*o);
+  gfs_object_simulation_set (d->D, gfs_object_simulation (d));
+  (* GTS_OBJECT (d->D)->klass->read) ((GtsObject **) &d->D, fp);
+}
+
+static void source_viscosity_write (GtsObject * o, FILE * fp)
+{
+  GfsSourceDiffusion * d = GFS_SOURCE_DIFFUSION (o);
+
+  (* GTS_OBJECT_CLASS (gfs_source_velocity_class ())->parent_class->write) (o, fp);
+  (* GTS_OBJECT (d->D)->klass->write) (GTS_OBJECT (d->D), fp);
+}
+
+static gdouble source_viscosity_non_diffusion_value (GfsSourceGeneric * s,
+						     FttCell * cell,
+						     GfsVariable * v)
+{
+  GfsVariable * mu = GFS_SOURCE_DIFFUSION (s)->D->mu;
+
+  if (mu == NULL)
+    return 0.;
+  else {
+    GfsVariable ** u = GFS_SOURCE_VISCOSITY (s)->v;
+    FttComponent c = v->component, j;
+    GfsFunction * alpha = gfs_object_simulation (s)->physical_params.alpha;
+    gdouble h = ftt_cell_size (cell);
+    gdouble a = 0.;
+
+    for (j = 0; j < FTT_DIMENSION; j++)
+      a += (gfs_center_gradient (cell, c, u[j]->i)*
+	    gfs_center_gradient (cell, j, mu->i));
+    return a*(alpha ? gfs_function_value (alpha, cell) : 1.)/(h*h);
+  }
+}
+
+static gdouble source_viscosity_value (GfsSourceGeneric * s,
+				       FttCell * cell,
+				       GfsVariable * v)
+{
+  return (source_diffusion_value (s, cell, v) +
+	  source_viscosity_non_diffusion_value (s, cell, v));
+}
+
+static void source_viscosity_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = source_viscosity_read;
+  GTS_OBJECT_CLASS (klass)->write = source_viscosity_write;
+}
+
+static void source_viscosity_init (GfsSourceGeneric * s)
+{
+  s->mac_value = source_viscosity_value;
+  s->centered_value = source_viscosity_non_diffusion_value;
+  s->flux = NULL;
+}
+
+GfsSourceGenericClass * gfs_source_viscosity_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_viscosity_info = {
+      "GfsSourceViscosity",
+      sizeof (GfsSourceViscosity),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_viscosity_class_init,
+      (GtsObjectInitFunc) source_viscosity_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_diffusion_class ()),
+				  &source_viscosity_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceViscosityExplicit: Object */
+
+static gdouble source_viscosity_stability (GfsSourceGeneric * s,
+					   GfsSimulation * sim)
+{
+  StabilityParams par;
+
+  par.s = s;
+  par.dtmax = G_MAXDOUBLE;
+  par.alpha = sim->physical_params.alpha;
+  gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) cell_diffusion_stability, &par);
+  return 0.1*par.dtmax;
+}
+
+static void source_viscosity_explicit_class_init (GfsSourceGenericClass * klass)
+{
+  klass->stability = source_viscosity_stability;
+}
+
+/* Defining this will use the divergence-free condition to decouple
+   the diffusion equations for each component. This only works of
+   course for constant viscosity and does not work for axisymmetric flows. */
+/* #define NOTRANSVERSE */
+
+static void add_viscosity_explicit_flux (FttCell * cell, FluxPar * p)
+{
+  FttCellFace f;
+  FttCellNeighbors n;
+  GfsGradient g = { 0., 0. };
+  gdouble v0;
+
+  if (GFS_IS_MIXED (cell)) {
+    if (((cell)->flags & GFS_FLAG_DIRICHLET) != 0)
+      g.b = gfs_cell_dirichlet_gradient_flux (cell, p->v->i, -1., 0.);
+  }
+
+  v0 = GFS_VARIABLE (cell, p->v->i);
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &n);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    GfsGradient e;
+
+    f.neighbor = n.c[f.d];
+    gfs_face_gradient_flux (&f, &e, p->v->i, -1);
+#ifndef NOTRANSVERSE
+    if (f.d/2 == p->v->component) {
+      e.a *= 2.;
+      e.b *= 2.;
+    }
+#endif
+    g.a += e.a;
+    g.b += e.b;
+  }
+
+  gdouble transverse = 0.;
+#ifndef NOTRANSVERSE
+#if FTT_2D
+  FttComponent ortho = (p->v->component + 1) % FTT_DIMENSION;
+
+  for (f.d = 2*ortho; f.d <= 2*ortho + 1; f.d++) {
+    f.neighbor = n.c[f.d];
+    transverse += (FTT_FACE_DIRECT (&f) ? 1. : -1.)*
+      gfs_face_weighted_interpolated_value (&f, p->tv->i);
+  }
+#else
+  g_assert_not_implemented ();
+#endif  
+#endif
+
+  GfsFunction * alpha = gfs_object_simulation (p->s)->physical_params.alpha;
+  gdouble h = ftt_cell_size (cell);
+  GFS_VALUE (cell, p->sv) += (alpha ? gfs_function_value (alpha, cell) : 1.)*
+    ((g.b - g.a*v0)/h + transverse)/h;
+}
+
+static void add_axisymmetric_term (FttCell * cell, FluxPar * p)
+{
+  GfsFunction * alpha = gfs_object_simulation (p->s)->physical_params.alpha;
+  gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+  GFS_VALUE (cell, p->sv) -= 
+    (alpha ? gfs_function_value (alpha, cell) : 1.)*
+    2.*gfs_source_diffusion_cell (GFS_SOURCE_DIFFUSION (p->s), cell)*
+    GFS_VALUE (cell, p->v)*
+    a*a/gfs_domain_cell_fraction (p->v->domain, cell)*
+    p->dt;
+}
+
+static void source_viscosity_explicit_flux (GfsSourceGeneric * s, 
+					    GfsDomain * domain, 
+					    GfsVariable * v, GfsVariable * sv, 
+					    gdouble dt)
+{
+  FluxPar p;
+
+  gfs_diffusion_coefficients (domain, GFS_SOURCE_DIFFUSION (s), dt, NULL, NULL, NULL, 1.);
+  gfs_domain_surface_bc (domain, v);
+  p.s = s;
+  p.v = v;
+  p.sv = sv;
+  p.dt = dt;
+  p.tv = gfs_temporary_variable (domain);
+  gfs_traverse_and_bc (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+		       (FttCellTraverseFunc) compute_transverse, &p,
+		       p.tv, p.tv);
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) add_viscosity_explicit_flux, &p);
+  if (GFS_IS_AXI (domain) && v->component == FTT_Y)
+    gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) add_axisymmetric_term, &p);
+  gts_object_destroy (GTS_OBJECT (p.tv));
+}
+
+static void source_viscosity_explicit_init (GfsSourceGeneric * s)
+{
+  s->mac_value = NULL;
+  s->centered_value = NULL;
+  s->flux = source_viscosity_explicit_flux;
+}
+
+GfsSourceGenericClass * gfs_source_viscosity_explicit_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo source_viscosity_explicit_info = {
+      "GfsSourceViscosityExplicit",
+      sizeof (GfsSourceViscosity),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) source_viscosity_explicit_class_init,
+      (GtsObjectInitFunc) source_viscosity_explicit_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_viscosity_class ()),
+				  &source_viscosity_explicit_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceCoriolis: Object */
+
+static void source_coriolis_destroy (GtsObject * o)
+{
+  FttComponent c;
+
+  if (GFS_SOURCE_CORIOLIS (o)->omegaz)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_CORIOLIS (o)->omegaz));
+  if (GFS_SOURCE_CORIOLIS (o)->drag)
+    gts_object_destroy (GTS_OBJECT (GFS_SOURCE_CORIOLIS (o)->drag));
+
+  for (c = 0; c <  2; c++)
+    if (GFS_SOURCE_CORIOLIS (o)->u[c])
+      gts_object_destroy (GTS_OBJECT (GFS_SOURCE_CORIOLIS (o)->u[c]));
+
+  (* GTS_OBJECT_CLASS (gfs_source_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_source_coriolis_read (GtsObject ** o, GtsFile * fp)
+{
+  FttComponent c;
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+
+  (* GTS_OBJECT_CLASS (gfs_source_coriolis_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    GfsVariable * v = GFS_SOURCE_VELOCITY (*o)->v[c];
+
+    if (v->sources) {
+      GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+      
+      while (i) {
+	if (i->data != *o && GFS_IS_SOURCE_CORIOLIS (i->data)) {
+	  gts_file_error (fp, "variable '%s' cannot have multiple Coriolis source terms", v->name);
+	  return;
+	}
+	i = i->next;
+      }
+    }
+  }
+
+  GFS_SOURCE_CORIOLIS (*o)->omegaz = gfs_function_new (gfs_function_class (), 0.);
+  gfs_function_read (GFS_SOURCE_CORIOLIS (*o)->omegaz, gfs_object_simulation (*o), fp);
+
+  if (fp->type != '\n') {
+    GFS_SOURCE_CORIOLIS (*o)->drag = gfs_function_new (gfs_function_class (), 0.);
+    gfs_function_read (GFS_SOURCE_CORIOLIS (*o)->drag, gfs_object_simulation (*o), fp);
+  }
+
+#if (!FTT_2D)
+  gts_container_remove (GFS_SOURCE_VELOCITY (*o)->v[FTT_Z]->sources, GTS_CONTAINEE (*o));
+#endif /* 3D */ 
+ 
+  for (c = 0; c <  2; c++)
+    GFS_SOURCE_CORIOLIS (*o)->u[c] = gfs_temporary_variable (domain);
+}
+
+static void gfs_source_coriolis_write (GtsObject * o, FILE * fp)
+{
+  GfsSourceCoriolis * s = GFS_SOURCE_CORIOLIS (o);
+
+  (* GTS_OBJECT_CLASS (gfs_source_coriolis_class ())->parent_class->write) (o, fp);
+  gfs_function_write (s->omegaz, fp);
+  if (s->drag)
+    gfs_function_write (s->drag, fp);
+}
+
+static gdouble gfs_source_coriolis_mac_value (GfsSourceGeneric * s,
+					      FttCell * cell,
+					      GfsVariable * v)
+{
+  GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (s);
+  GfsSourceCoriolis * sc = GFS_SOURCE_CORIOLIS (s);
+  gdouble f = gfs_function_value (sc->omegaz, cell);
+  gdouble e = sc->drag ? gfs_function_value (sc->drag, cell) : 0.;
+
+  switch (v->component) {
+  case FTT_X: return - e*GFS_VALUE (cell, sv->v[0]) + f*GFS_VALUE (cell, sv->v[1]);
+  case FTT_Y: return - f*GFS_VALUE (cell, sv->v[0]) - e*GFS_VALUE (cell, sv->v[1]);
+  default: g_assert_not_reached ();
+  }
+  return 0.;
+}
+
+static void save_coriolis (FttCell * cell, GfsSourceCoriolis * s)
+{
+  GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (s);
+  gdouble f = gfs_function_value (s->omegaz, cell)/2.;
+  gdouble e = s->drag ? gfs_function_value (s->drag, cell)/2. : 0.;
+
+  GFS_VALUE (cell, s->u[0]) = - e*GFS_VALUE (cell, sv->v[0]) + f*GFS_VALUE (cell, sv->v[1]);
+  GFS_VALUE (cell, s->u[1]) = - f*GFS_VALUE (cell, sv->v[0]) - e*GFS_VALUE (cell, sv->v[1]);
+}
+
+static gboolean gfs_source_coriolis_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_event_sum_class ())->parent_class)->event) (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) save_coriolis, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gdouble gfs_source_coriolis_centered_value (GfsSourceGeneric * s,
+						   FttCell * cell,
+						   GfsVariable * v)
+{
+  return GFS_VALUE (cell, GFS_SOURCE_CORIOLIS (s)->u[v->component]);
+}
+
+static void gfs_source_coriolis_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = source_coriolis_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_source_coriolis_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_source_coriolis_write;
+
+  GFS_EVENT_CLASS (klass)->event = gfs_source_coriolis_event;
+}
+
+static void gfs_source_coriolis_init (GfsSourceGeneric * s)
+{
+  s->mac_value = gfs_source_coriolis_mac_value;
+  s->centered_value = gfs_source_coriolis_centered_value;
+}
+
+GfsSourceGenericClass * gfs_source_coriolis_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_coriolis_info = {
+      "GfsSourceCoriolis",
+      sizeof (GfsSourceCoriolis),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_coriolis_class_init,
+      (GtsObjectInitFunc) gfs_source_coriolis_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_velocity_class ()),
+				  &gfs_source_coriolis_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_has_source_coriolis:
+ * @domain: a #GfsDomain.
+ *
+ * Returns: the #GfsSourceCoriolis associated with @domain or %NULL.
+ */
+GfsSourceCoriolis * gfs_has_source_coriolis (GfsDomain * domain)
+{
+  GfsVariable * v;
+
+  g_return_val_if_fail (domain != NULL, NULL);
+
+  v = gfs_variable_from_name (domain->variables, "U");
+  g_return_val_if_fail (v != NULL, NULL);
+
+  if (v->sources) {
+    GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+
+    while (i) {
+      if (GFS_IS_SOURCE_CORIOLIS (i->data))
+	return i->data;
+      i = i->next;
+    }
+  }
+  return NULL;
+}
+
+static void implicit_coriolis (FttCell * cell, GfsSourceCoriolis * s)
+{
+  GfsSourceVelocity * sv = GFS_SOURCE_VELOCITY (s);
+  gdouble c, u, v;
+  GfsSimulation * sim = gfs_object_simulation (s);
+
+  c = sim->advection_params.dt*gfs_function_value (s->omegaz, cell)/2.;
+  u = GFS_VALUE (cell, sv->v[0]);
+  v = GFS_VALUE (cell, sv->v[1]);
+  if (s->drag) {
+    gdouble e = sim->advection_params.dt*gfs_function_value (s->drag, cell)/2.;
+    GFS_VALUE (cell, sv->v[0]) = (u + c*v/(1. + e))/((1. + e) + c*c/(1. + e));
+    GFS_VALUE (cell, sv->v[1]) = (v - c*u/(1. + e))/((1. + e) + c*c/(1. + e));
+  }
+  else {
+    GFS_VALUE (cell, sv->v[0]) = (u + c*v)/(1. + c*c);
+    GFS_VALUE (cell, sv->v[1]) = (v - c*u)/(1. + c*c);
+  }
+}
+
+/**
+ * gfs_source_coriolis_implicit:
+ * @domain: a #GfsDomain.
+ * @dt: the timestep.
+ *
+ * Applies the implicit part of the Coriolis source term of @domain.
+ */
+void gfs_source_coriolis_implicit (GfsDomain * domain,
+				   gdouble dt)
+{
+  GfsSourceCoriolis * s;
+
+  g_return_if_fail (domain != NULL);
+
+  if ((s = gfs_has_source_coriolis (domain))) {
+    GfsSimulation * sim = GFS_SIMULATION (domain);
+    gdouble olddt = sim->advection_params.dt;
+    sim->advection_params.dt = dt;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) implicit_coriolis, s);
+    sim->advection_params.dt = olddt;
+  }
+}
diff --git a/src/source.h b/src/source.h
new file mode 100644
index 0000000..536626e
--- /dev/null
+++ b/src/source.h
@@ -0,0 +1,340 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __SOURCE_H__
+#define __SOURCE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "event.h"
+
+gdouble    gfs_variable_mac_source     (GfsVariable * v, 
+					FttCell * cell);
+void       gfs_domain_variable_centered_sources (GfsDomain * domain, 
+						 GfsVariable * v,
+						 GfsVariable * sv,
+						 gdouble dt);
+GfsVariable * gfs_domain_variable_fluxes        (GfsDomain * domain,
+						 GfsVariable * v,
+						 gdouble dt);
+
+/* GfsSourceGeneric: Header */
+
+typedef struct _GfsSourceGeneric         GfsSourceGeneric;
+
+struct _GfsSourceGeneric {
+  /*< private >*/
+  GfsEvent parent;
+
+  /*< public >*/
+  GfsVariable * v;
+  gdouble (* mac_value)      (GfsSourceGeneric *, FttCell *, GfsVariable *);
+  gdouble (* centered_value) (GfsSourceGeneric *, FttCell *, GfsVariable *);
+  gdouble (* face_value)     (GfsSourceGeneric *, FttCellFace *, GfsVariable *);
+  void    (* flux)           (GfsSourceGeneric *, GfsDomain *, 
+			      GfsVariable *, GfsVariable *, 
+			      gdouble);
+};
+
+typedef struct _GfsSourceGenericClass    GfsSourceGenericClass;
+
+struct _GfsSourceGenericClass {
+  /*< private >*/
+  GfsEventClass parent_class;
+
+  /*< public >*/
+  gdouble (* stability)      (GfsSourceGeneric *, GfsSimulation *);
+};
+
+#define GFS_SOURCE_GENERIC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceGeneric,\
+					         gfs_source_generic_class ())
+#define GFS_SOURCE_GENERIC_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsSourceGenericClass,\
+						 gfs_source_generic_class())
+#define GFS_IS_SOURCE_GENERIC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_generic_class ()))
+
+GfsSourceGenericClass * gfs_source_generic_class  (void);
+GfsSourceGeneric *      gfs_source_find           (GfsVariable * v,
+						   GfsSourceGenericClass * klass);
+
+/* GfsSourceScalar: Header */
+
+typedef struct _GfsSourceScalar         GfsSourceScalar;
+
+struct _GfsSourceScalar {
+  /*< private >*/
+  GfsSourceGeneric parent;
+
+  /*< public >*/
+  GfsVariable * v;
+};
+
+#define GFS_SOURCE_SCALAR(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceScalar,\
+					         gfs_source_scalar_class ())
+#define GFS_IS_SOURCE_SCALAR(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_scalar_class ()))
+
+GfsSourceGenericClass * gfs_source_scalar_class  (void);
+
+/* GfsSourceVelocity: Header */
+
+typedef struct _GfsSourceVelocity         GfsSourceVelocity;
+
+struct _GfsSourceVelocity {
+  /*< private >*/
+  GfsSourceGeneric parent;
+
+  /*< public >*/
+  GfsVariable ** v;
+};
+
+#define GFS_SOURCE_VELOCITY(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceVelocity,\
+					         gfs_source_velocity_class ())
+#define GFS_IS_SOURCE_VELOCITY(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_velocity_class ()))
+
+GfsSourceGenericClass * gfs_source_velocity_class  (void);
+
+/* GfsSource: Header */
+
+typedef struct _GfsSource         GfsSource;
+
+struct _GfsSource {
+  /*< private >*/
+  GfsSourceScalar parent;
+
+  /*< public >*/
+  GfsFunction * intensity;
+};
+
+#define GFS_SOURCE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSource,\
+					         gfs_source_class ())
+#define GFS_IS_SOURCE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_class ()))
+
+GfsSourceGenericClass * gfs_source_class  (void);
+
+/* GfsSourceControl: Header */
+
+typedef struct _GfsSourceControl         GfsSourceControl;
+
+struct _GfsSourceControl {
+  /*< private >*/
+  GfsSourceScalar parent;
+  gdouble s;
+
+  /*< public >*/
+  GfsFunction * intensity;
+};
+
+#define GFS_SOURCE_CONTROL(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceControl,\
+					         gfs_source_control_class ())
+#define GFS_IS_SOURCE_CONTROL(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_control_class ()))
+
+GfsSourceGenericClass * gfs_source_control_class  (void);
+
+/* GfsSourceControlField: Header */
+
+typedef struct _GfsSourceControlField         GfsSourceControlField;
+
+struct _GfsSourceControlField {
+  /*< private >*/
+  GfsSourceControl parent;
+  GfsVariable * s;
+
+  /*< public >*/
+  gint level;
+};
+
+#define GFS_SOURCE_CONTROL_FIELD(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceControlField,\
+					         gfs_source_control_field_class ())
+#define GFS_IS_SOURCE_CONTROL_FIELD(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_control_field_class ()))
+
+GfsSourceGenericClass * gfs_source_control_field_class  (void);
+
+/* GfsSourceFlux: Header */
+
+typedef struct _GfsSourceFlux         GfsSourceFlux;
+
+struct _GfsSourceFlux {
+  /*< private >*/
+  GfsSourceScalar parent;
+  gdouble s;
+
+  /*< public >*/
+  GfsFunction * intensity, * fraction;
+};
+
+#define GFS_SOURCE_FLUX(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceFlux,\
+					         gfs_source_flux_class ())
+#define GFS_IS_SOURCE_FLUX(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_flux_class ()))
+
+GfsSourceGenericClass * gfs_source_flux_class  (void);
+
+/* GfsDiffusion: Header */
+
+typedef struct _GfsDiffusion         GfsDiffusion;
+
+struct _GfsDiffusion {
+  /*< private >*/
+  GfsEvent parent;
+
+  /*< public >*/
+  GfsFunction * val;
+  GfsVariable * mu;
+  GfsMultilevelParams par;
+};
+
+typedef struct _GfsDiffusionClass    GfsDiffusionClass;
+
+struct _GfsDiffusionClass {
+  /*< private >*/
+  GfsEventClass parent_class;
+
+  /*< public >*/
+  gdouble (* face)  (GfsDiffusion *, FttCellFace *);
+  gdouble (* cell)  (GfsDiffusion *, FttCell *);
+};
+
+#define GFS_DIFFUSION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsDiffusion,\
+					         gfs_diffusion_class ())
+#define GFS_DIFFUSION_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsDiffusionClass,\
+						 gfs_diffusion_class())
+#define GFS_IS_DIFFUSION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_diffusion_class ()))
+
+GfsDiffusionClass * gfs_diffusion_class  (void);
+gdouble             gfs_diffusion_face   (GfsDiffusion * d, 
+					  FttCellFace * f);
+gdouble             gfs_diffusion_cell   (GfsDiffusion * d, 
+					  FttCell * cell);
+
+/* GfsSourceDiffusion: Header */
+
+struct _GfsSourceDiffusion {
+  /*< private >*/
+  GfsSourceScalar parent;
+
+  /*< public >*/
+  GfsDiffusion * D;
+};
+
+#define GFS_SOURCE_DIFFUSION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceDiffusion,\
+					         gfs_source_diffusion_class ())
+#define GFS_IS_SOURCE_DIFFUSION(obj)         (gts_object_is_from_class (obj,\
+						gfs_source_diffusion_class ()))
+
+GfsSourceGenericClass *   gfs_source_diffusion_class  (void);
+gdouble                   gfs_source_diffusion_face   (GfsSourceDiffusion * d, 
+						       FttCellFace * f);
+gdouble                   gfs_source_diffusion_cell   (GfsSourceDiffusion * d, 
+						       FttCell * cell);
+
+/* GfsSourceDiffusionExplicit: Header */
+
+typedef struct _GfsSourceDiffusionExplicit         GfsSourceDiffusionExplicit;
+
+struct _GfsSourceDiffusionExplicit {
+  /*< private >*/
+  GfsSourceDiffusion parent;
+
+  /*< public >*/
+  GfsVariable * s;
+};
+
+#define GFS_SOURCE_DIFFUSION_EXPLICIT(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceDiffusionExplicit,\
+					         gfs_source_diffusion_explicit_class ())
+#define GFS_IS_SOURCE_DIFFUSION_EXPLICIT(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_diffusion_explicit_class ()))
+
+GfsSourceGenericClass * gfs_source_diffusion_explicit_class  (void);
+
+/* GfsSourceViscosity: Header */
+
+typedef struct _GfsSourceViscosity         GfsSourceViscosity;
+
+struct _GfsSourceViscosity {
+  /*< private >*/
+  GfsSourceDiffusion parent;
+
+  /*< public >*/
+  GfsVariable ** v;
+};
+
+#define GFS_SOURCE_VISCOSITY(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceViscosity,\
+					         gfs_source_viscosity_class ())
+#define GFS_IS_SOURCE_VISCOSITY(obj) (gts_object_is_from_class (obj,\
+				       gfs_source_viscosity_class ()))
+
+GfsSourceGenericClass * gfs_source_viscosity_class  (void);
+
+/* GfsSourceViscosityExplicit: Header */
+
+#define GFS_IS_SOURCE_VISCOSITY_EXPLICIT(obj) (gts_object_is_from_class (obj,\
+					       gfs_source_viscosity_explicit_class ()))
+
+GfsSourceGenericClass * gfs_source_viscosity_explicit_class  (void);
+
+/* GfsSourceCoriolis: Header */
+
+typedef struct _GfsSourceCoriolis         GfsSourceCoriolis;
+
+struct _GfsSourceCoriolis {
+  /*< private >*/
+  GfsSourceVelocity parent;
+  GfsVariable * u[2];
+
+  /*< public >*/
+  GfsFunction * omegaz, * drag;
+};
+
+#define GFS_SOURCE_CORIOLIS(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceCoriolis,\
+					         gfs_source_coriolis_class ())
+#define GFS_IS_SOURCE_CORIOLIS(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_coriolis_class ()))
+
+GfsSourceGenericClass * gfs_source_coriolis_class    (void);
+void                    gfs_source_coriolis_implicit (GfsDomain * domain,
+						      gdouble dt);
+GfsSourceCoriolis *     gfs_has_source_coriolis      (GfsDomain * domain);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SOURCE_H__ */
diff --git a/src/spatial.h b/src/spatial.h
new file mode 100644
index 0000000..553cd26
--- /dev/null
+++ b/src/spatial.h
@@ -0,0 +1,54 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __SPATIAL_H__
+#define __SPATIAL_H__
+
+/* When modifying this file, please also update the documentation at:
+ * http://gfs.sourceforge.net/wiki/index.php/GfsSurface
+ */
+
+#define intersection(a,b) MAX(a, b)
+#define union(a,b)        MIN(a, b)
+#define difference(a,b)   MAX(a, -(b))
+
+static double _x = 0., _y = 0., _z = 0.;
+
+static double ellipse (double xc, double yc, double a, double b)
+{
+  g_return_val_if_fail (a != 0. && b != 0., 0.);
+  return (_x - xc)*(_x - xc)/(a*a) + (_y - yc)*(_y - yc)/(b*b) - 1.;
+}
+
+static double sphere (double xc, double yc, double zc, double r)
+{
+  return (_x - xc)*(_x - xc) + (_y - yc)*(_y - yc) + (_z - zc)*(_z - zc) - r*r;
+}
+
+static double cube (double xc, double yc, double zc, double h)
+{
+  double vmax = (_x - xc)*(_x - xc) - h*h/4.;
+  double v = (_y - yc)*(_y - yc) - h*h/4.;
+  if (v > vmax) vmax = v;
+  v = (_z - zc)*(_z - zc) - h*h/4.;
+  if (v > vmax) vmax = v;
+  return vmax;
+}
+
+#endif /* __SPATIAL_H__ */
diff --git a/src/surface.c b/src/surface.c
new file mode 100644
index 0000000..5c9dbfa
--- /dev/null
+++ b/src/surface.c
@@ -0,0 +1,851 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+
+#include "simulation.h"
+#include "surface.h"
+
+/* GfsGenericSurface: Object */
+
+GfsGenericSurfaceClass * gfs_generic_surface_class (void)
+{
+  static GfsGenericSurfaceClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_generic_surface_info = {
+      "GfsGenericSurface",
+      sizeof (GtsObject),
+      sizeof (GfsGenericSurfaceClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_generic_surface_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_cell_is_cut:
+ * @cell: a #FttCell.
+ * @s: a #GfsGenericSurface.
+ * @flatten: if set to %TRUE, @cell is flattened in the z direction.
+ * @maxlevel: the maximum (virtual) cell level to consider.
+ *
+ * Returns: a (possibly new) #GfsGenericSurface containing a subset of @s which may
+ * intersect @cell or %NULL if @s does not intersect @cell.
+ */
+GfsGenericSurface * gfs_cell_is_cut (FttCell * cell, GfsGenericSurface * s, 
+				     gboolean flatten, gint maxlevel)
+{
+  g_return_val_if_fail (cell != NULL, NULL);
+  g_return_val_if_fail (s != NULL, NULL);
+  
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->cell_is_cut);
+  return (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->cell_is_cut) 
+    (cell, s, flatten, maxlevel);
+}
+
+static void cell_traverse_cut (FttCell * cell,
+			       GfsGenericSurface * s,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       FttCellTraverseCutFunc func,
+			       gpointer data,
+			       gboolean flatten)
+{
+  GfsGenericSurface * s1 = gfs_cell_is_cut (cell, s, flatten && FTT_CELL_IS_LEAF (cell), -1);
+
+  if (s1 == NULL)
+    return;
+  if (order == FTT_PRE_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, s1, data);
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    struct _FttOct * children = cell->children;
+    guint n;
+
+    for (n = 0; n < FTT_CELLS; n++) {
+      FttCell * c = &(children->cell[n]);
+
+      if ((flags & FTT_TRAVERSE_DESTROYED) != 0 || !FTT_CELL_IS_DESTROYED (c))
+	cell_traverse_cut (c, s1, order, flags, func, data, flatten);
+    }
+  }
+  if (order == FTT_POST_ORDER &&
+      (flags == FTT_TRAVERSE_ALL ||
+       ((flags & FTT_TRAVERSE_LEAFS) != 0 && FTT_CELL_IS_LEAF (cell)) ||
+       ((flags & FTT_TRAVERSE_NON_LEAFS) != 0 && !FTT_CELL_IS_LEAF (cell))))
+    (* func) (cell, s1, data);
+  if (s1 != s)
+    gts_object_destroy (GTS_OBJECT (s1));
+}
+
+/**
+ * gfs_cell_traverse_cut:
+ * @root: the root #FttCell of the tree to traverse.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * 
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell cut by @s.
+ */
+void gfs_cell_traverse_cut (FttCell * root,
+			    GfsGenericSurface * s,
+			    FttTraverseType order,
+			    FttTraverseFlags flags,
+			    FttCellTraverseCutFunc func,
+			    gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  cell_traverse_cut (root, s, order, flags, func, data, FALSE);
+}
+
+/**
+ * gfs_cell_traverse_cut_2D:
+ * @root: the root #FttCell of the tree to traverse.
+ * @s: a #GfsGenericSurface.
+ * @order: the order in which the cells are visited - %FTT_PRE_ORDER,
+ * %FTT_POST_ORDER. 
+ * @flags: which types of children are to be visited.
+ * @func: the function to call for each visited #FttCell.
+ * @data: user data to pass to @func.
+ * 
+ * Traverses a cell tree starting at the given root #FttCell. Calls
+ * the given function for each cell cut by @s.
+ *
+ * The cells are "flattened" in the z-direction.
+ */
+void gfs_cell_traverse_cut_2D (FttCell * root,
+			       GfsGenericSurface * s,
+			       FttTraverseType order,
+			       FttTraverseFlags flags,
+			       FttCellTraverseCutFunc func,
+			       gpointer data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (func != NULL);
+
+  cell_traverse_cut (root, s, order, flags, func, data, TRUE);
+}
+
+/**
+ * gfs_generic_surface_read:
+ * @s: a #GfsGenericSurface.
+ * @sim: a #GfsSimulation.
+ * @fp: a #GtsFile.
+ * 
+ * Calls the read() method of @s.
+ */
+void gfs_generic_surface_read (GfsGenericSurface * s, gpointer sim, GtsFile * fp)
+{
+  GtsObject * o = (GtsObject *) s;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (fp != NULL);
+
+  o->reserved = sim;
+  (* GTS_OBJECT (s)->klass->read) (&o, fp);
+}
+
+/**
+ * gfs_generic_surface_write:
+ * @s: a #GfsGenericSurface.
+ * @sim: a #GfsSimulation.
+ * @fp: a file pointer.
+ * 
+ * Calls the write() method of @s.
+ */
+void gfs_generic_surface_write (GfsGenericSurface * s, gpointer sim, FILE * fp)
+{
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GTS_OBJECT (s)->reserved = sim;
+  (* GTS_OBJECT (s)->klass->write) (GTS_OBJECT (s), fp);
+}
+
+/**
+ * gfs_surface_segment_intersection:
+ * @s: a #GfsGenericSurface.
+ * @cell: a #FttCell containing @I.
+ * @I: a GfsSegment.
+ *
+ * Fills @I with the intersection of @s and @I.
+ *
+ * Returns: the number of times @s intersects @I.
+ */
+guint gfs_surface_segment_intersection (GfsGenericSurface * s,
+					FttCell * cell,
+					GfsSegment * I)
+{
+  g_return_val_if_fail (s != NULL, 0);
+  g_return_val_if_fail (cell != NULL, 0);
+  g_return_val_if_fail (I != NULL, 0);
+
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_intersection);
+  return (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_intersection) (s, cell, I);
+}
+
+/**
+ * gfs_surface_segment_normal:
+ * @s: a #GfsGenericSurface.
+ * @cell: a #FttCell containing @I.
+ * @I: a GfsSegment.
+ * @n: a #GtsVector.
+ *
+ * Fills @n with the normal to @s at the intersection of @s and @I.
+ */
+void gfs_surface_segment_normal (GfsGenericSurface * s,
+				 FttCell * cell,
+				 GfsSegment * I,
+				 GtsVector n)
+{
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (I != NULL);
+  g_return_if_fail (I->n > 0);
+  g_return_if_fail (n != NULL);
+
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_normal);
+  (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->segment_normal) (s, cell, I, n);
+}
+
+/**
+ * gfs_surface_point_is_inside:
+ * @s: a #GfsGenericSurface.
+ * @p: a #FttVector.
+ *
+ * Returns: 1 if @p is inside @s, 0 if @p lies on the boundary of @s,
+ * -1 otherwise.
+ */
+gint gfs_surface_point_is_inside (GfsGenericSurface * s,
+				  FttVector * p)
+{
+  g_return_val_if_fail (s != NULL, 0);
+  g_return_val_if_fail (p != NULL, 0);
+
+  g_assert (GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->point_is_inside);
+  return (* GFS_GENERIC_SURFACE_CLASS (GTS_OBJECT (s)->klass)->point_is_inside) (s, p);
+}
+
+/* GfsSurface: Object */
+
+static void check_solid_surface (GtsSurface * s, 
+				 const gchar * fname,
+				 GtsFile * fp)
+{
+  GString * name = g_string_new ("surface");
+
+  if (fname) {
+    g_string_append (name, " `");
+    g_string_append (name, fname);
+    g_string_append_c (name, '\'');
+  }
+
+  if (!gts_surface_is_orientable (s))
+    gts_file_error (fp, "%s is not orientable", name->str);
+  g_string_free (name, TRUE);
+}
+
+/**
+ * gfs_surface_transformation:
+ * @surface: a #GtsSurface
+ * @rotate: a #GtsVector
+ * @translate: a #GtsVector 
+ * @scale: a #GtsVector
+ * @s: a #gdouble
+ * @flip: a #gboolean
+ * @matrix: a pointer on a #GtsMatrix
+ * 
+ * Translates, rotates, scales and flips @surface.
+ */
+void gfs_surface_transformation (GtsSurface * surface, 
+				 GtsVector rotate,
+				 GtsVector translate, 
+				 GtsVector scale,
+				 gboolean flip,
+				 GtsMatrix ** matrix)
+{
+  GtsMatrix * m;
+  gint c;
+
+  g_return_if_fail (matrix != NULL);
+  
+  m = gts_matrix_translate (NULL, translate);    
+  for (c = 2; c >= 0; c--)
+    if (rotate[c] != 0.) {
+      GtsVector r = {0.,0.,0.};
+      r[c] = 1.;
+      GtsMatrix * mr = gts_matrix_rotate (NULL, r, rotate[c]*M_PI/180.);
+      GtsMatrix * m1 = gts_matrix_product (m, mr);
+      gts_matrix_destroy (m);
+      gts_matrix_destroy (mr);
+      m = m1;
+    }
+
+  GtsMatrix * ms = gts_matrix_scale (NULL, scale);
+  if (*matrix)
+    gts_matrix_destroy (*matrix);
+  *matrix = gts_matrix_product (m, ms);
+  gts_matrix_destroy (m);
+  gts_matrix_destroy (ms);
+  
+  if (surface) {
+    gts_surface_foreach_vertex (surface, (GtsFunc) gts_point_transform, *matrix);
+    gts_matrix_destroy (*matrix);
+    *matrix = NULL;
+    if (flip)
+      gts_surface_foreach_face (surface, (GtsFunc) gts_triangle_revert, NULL);
+  }
+  else {
+    GtsMatrix * i = gts_matrix_inverse (*matrix);
+    gts_matrix_destroy (*matrix);
+    *matrix = i;
+  }
+}
+
+static void point_map (GtsPoint * p, GfsSimulation * sim)
+{
+  gfs_simulation_map (sim, (FttVector *) &p->x);
+}
+
+static void surface_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSurface * surface = GFS_SURFACE (*o);
+  gboolean dimensional = FALSE;
+
+  if (fp->type == '(') { /* implicit surface */
+    gts_file_next_token (fp);
+    if (surface->f)
+      gts_object_destroy (GTS_OBJECT (surface->f));
+    surface->f = gfs_function_new (gfs_function_spatial_class (), 0.);
+    gfs_function_read (surface->f, gfs_object_simulation (*o), fp);
+    if (fp->type == GTS_ERROR)
+      return;
+    if (fp->type != ')') {
+      gts_file_error (fp, "expecting a closing bracket");
+      return;
+    }
+  }
+  else if (fp->type == '{') { /* embedded surface */
+    fp->scope_max++;
+    gts_file_next_token (fp);
+    if (surface->s)
+      gts_object_destroy (GTS_OBJECT (surface->s));
+    surface->s = gts_surface_new (gts_surface_class (), 
+				  gts_face_class (), 
+				  gts_edge_class (), 
+				  gts_vertex_class ());
+    if (gts_surface_read (surface->s, fp))
+      return;
+    if (fp->type != '}') {
+      gts_file_error (fp, "expecting a closing brace");
+      return;
+    }
+    check_solid_surface (surface->s, NULL, fp);
+    if (fp->type == GTS_ERROR)
+      return;
+    fp->scope_max--;
+  }
+  else { /* surface file name */
+    if (fp->type != GTS_STRING) {
+      gts_file_error (fp, "expecting a string (filename)");
+      return;
+    }
+    FILE * fptr = fopen (fp->token->str, "rt");
+    if (fptr == NULL) {
+      gts_file_error (fp, "cannot open file `%s'", fp->token->str);
+      return;
+    }
+    GtsFile * fp1 = gts_file_new (fptr);
+    surface->s = gts_surface_new (gts_surface_class (), 
+				  gts_face_class (), 
+				  gts_edge_class (), 
+				  gts_vertex_class ());
+    if (gts_surface_read (surface->s, fp1)) {
+      gts_file_error (fp, 
+		      "file `%s' is not a valid GTS file\n"
+		      "%s:%d:%d: %s",
+		      fp->token->str, fp->token->str,
+		      fp1->line, fp1->pos, fp1->error);
+      gts_file_destroy (fp1);
+      fclose (fptr);
+      return;
+    }
+    gts_file_destroy (fp1);
+    fclose (fptr);
+    check_solid_surface (surface->s, fp->token->str, fp);
+    if (fp->type == GTS_ERROR)
+      return;
+    dimensional = TRUE;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type == '{') {
+    gdouble scale = 1.;
+    GtsFileVariable var[] = {
+      {GTS_DOUBLE, "rx", TRUE},
+      {GTS_DOUBLE, "ry", TRUE},
+      {GTS_DOUBLE, "rz", TRUE},
+      {GTS_DOUBLE, "sx", TRUE},
+      {GTS_DOUBLE, "sy", TRUE},
+      {GTS_DOUBLE, "sz", TRUE},
+      {GTS_DOUBLE, "tx", TRUE},
+      {GTS_DOUBLE, "ty", TRUE},
+      {GTS_DOUBLE, "tz", TRUE},
+      {GTS_DOUBLE, "scale", TRUE},
+      {GTS_INT,    "flip", TRUE},
+      {GTS_INT,    "twod", TRUE},
+      {GTS_NONE}
+    };
+    GtsFileVariable * v = var;
+
+    (v++)->data = &surface->rotate[0];
+    (v++)->data = &surface->rotate[1];
+    (v++)->data = &surface->rotate[2];
+
+    (v++)->data = &surface->scale[0];
+    (v++)->data = &surface->scale[1];
+    (v++)->data = &surface->scale[2];
+
+    (v++)->data = &surface->translate[0];
+    (v++)->data = &surface->translate[1];
+    (v++)->data = &surface->translate[2];
+
+    (v++)->data = &scale;
+
+    (v++)->data = &surface->flip;
+    (v++)->data = &surface->twod;
+
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+
+    gboolean set = FALSE;
+    guint i;
+    for (i = 0; i < 11 && !set; i++)
+      if (var[i].set)
+	set = TRUE;
+
+    if (set) {
+      if (var[9].set) {
+	surface->scale[0] *= scale;
+	surface->scale[1] *= scale;
+	surface->scale[2] *= scale;
+      }
+      gfs_surface_transformation (surface->s, 
+				  surface->rotate, surface->translate, surface->scale,
+				  surface->flip, 
+				  &surface->m);
+    }
+  }
+
+  if (dimensional) {
+    g_assert (surface->s);
+    gts_surface_foreach_vertex (surface->s, (GtsFunc) point_map, gfs_object_simulation (*o));
+  }
+}
+
+static void surface_write (GtsObject * o, FILE * fp)
+{
+  GfsSurface * surface = GFS_SURFACE (o);
+  if (surface->s) {
+    fputs (" { ", fp);
+    GtsSurface * s = surface->s;
+    if (GFS_DOMAIN (gfs_object_simulation (o))->binary) {
+      gboolean binary = GTS_POINT_CLASS (s->vertex_class)->binary;
+      GTS_POINT_CLASS (s->vertex_class)->binary = TRUE;
+      gts_surface_write (s, fp);
+      GTS_POINT_CLASS (s->vertex_class)->binary = binary;
+    }
+    else
+      gts_surface_write (s, fp);
+    fputc ('}', fp);
+  }
+  else if (surface->f) {
+    fputs (" (", fp);
+    gfs_function_write (surface->f, fp);
+    fputs (" )", fp);
+  }
+  if (surface->m) {
+    fputs (" {\n", fp);
+    if (gts_vector_norm (surface->translate) > 0.)
+      fprintf (fp, "  tx = %g ty = %g tz = %g\n",
+	       surface->translate[0], surface->translate[1], surface->translate[2]);
+    if (surface->scale[0] != 1. || surface->scale[1] != 1. || surface->scale[2] != 1.)
+      fprintf (fp, "  sx = %g sy = %g sz = %g\n",
+	       surface->scale[0], surface->scale[1], surface->scale[2]);
+    if (surface->rotate[0] != 0.)
+      fprintf (fp, "  rx = %g\n", surface->rotate[0]);
+    if (surface->rotate[1] != 0.)
+      fprintf (fp, "  ry = %g\n", surface->rotate[1]);
+    if (surface->rotate[2] != 0.)
+      fprintf (fp, "  rz = %g\n", surface->rotate[2]);
+    if (surface->flip)
+      fputs ("  flip = 1\n", fp);
+    if (surface->twod)
+      fputs ("  twod = 1\n", fp);
+    fputc ('}', fp);
+  }
+  else
+    fputs (" {}", fp);
+}
+
+static void surface_destroy (GtsObject * object)
+{
+  GfsSurface * s = GFS_SURFACE (object);
+  if (s->s)
+    gts_object_destroy (GTS_OBJECT (s->s));
+  if (s->f)
+    gts_object_destroy (GTS_OBJECT (s->f));
+  if (s->m)
+    gts_matrix_destroy (s->m);
+
+  (* GTS_OBJECT_CLASS (gfs_surface_class ())->parent_class->destroy) (object);
+}
+
+
+static void face_overlaps_box (GtsTriangle * t, gpointer * data)
+{
+  GtsBBox * bb = data[0];
+  GtsSurface ** s1 = data[1];
+
+  if (gts_bbox_overlaps_triangle (bb, t)) {
+    if (*s1 == NULL)
+      *s1 = gts_surface_new (gts_surface_class (),
+			     gts_face_class (),
+			     gts_edge_class (),
+			     gts_vertex_class ());
+    gts_surface_add_face (*s1, GTS_FACE (t));
+  }
+}
+
+#define SIGN(v) ((v) > 0. ? 1 : (v) < 0. ? -1 : 0)
+
+static GfsGenericSurface * cell_is_cut (FttCell * cell, GfsGenericSurface * s1, 
+					gboolean flatten, gint maxlevel)
+{
+  GfsSurface * s = GFS_SURFACE (s1);
+  if (s->s) {
+    GtsSurface * s1 = NULL;
+    gpointer data[2];
+    GtsBBox bb;
+    ftt_cell_bbox (cell, &bb);
+    if (flatten)
+      bb.z1 = bb.z2 = 0.;
+    data[0] = &bb;
+    data[1] = &s1;
+    gts_surface_foreach_face (s->s, (GtsFunc) face_overlaps_box, data);
+    if (s1 == NULL)
+      return NULL;
+    GfsSurface * s2 = GFS_SURFACE (gts_object_new (GTS_OBJECT_CLASS (gfs_surface_class ())));
+    s2->s = s1;
+    return GFS_GENERIC_SURFACE (s2);
+  }
+  else if (s->f) {
+    if (!FTT_CELL_IS_LEAF (cell))
+      return GFS_GENERIC_SURFACE (s);
+    FttVector p;
+    gdouble h = ftt_cell_size (cell)/2.;
+    ftt_cell_pos (cell, &p);
+    gint i, j, k = 0, sign = 0, n = 1;
+    i = maxlevel - ftt_cell_level (cell);
+    while (i-- > 0)
+      n *= 2;
+#if !FTT_2D
+    for (k = - n; k <= n; k += 2)
+#endif
+      for (i = - n; i <= n; i += 2)
+	for (j = - n; j <= n; j += 2) {
+	  GtsPoint o;
+	  o.x = p.x + i*h/n; o.y = p.y + j*h/n; o.z = p.z + k*h/n;
+	  gdouble v = gfs_surface_implicit_value (s, o);
+	  if (sign && sign*SIGN(v) <= 0)
+	    return GFS_GENERIC_SURFACE (s);
+	  sign = SIGN(v);
+	}
+    return NULL;
+  }
+  g_assert_not_reached ();
+  return NULL;
+}
+
+static gdouble segment_triangle_intersection (GtsPoint * E, GtsPoint * D,
+					      GtsTriangle * t,
+					      gboolean * inside)
+{
+  GtsVertex * vA, * vB, * vC;
+  GtsPoint * A, * B, * C;
+  gint ABCE, ABCD, ADCE, ABDE, BCDE;
+  GtsEdge * AB, * BC, * CA;
+  gdouble a, b;
+  gboolean reversed = FALSE;
+
+  gts_triangle_vertices_edges (t, NULL, &vA, &vB, &vC, &AB, &BC, &CA);
+  A = GTS_POINT (vA);
+  B = GTS_POINT (vB);
+  C = GTS_POINT (vC);
+  ABCE = gts_point_orientation_3d_sos (A, B, C, E);
+  ABCD = gts_point_orientation_3d_sos (A, B, C, D);
+  if (ABCE < 0 || ABCD > 0) {
+    GtsPoint * tmpp;
+    gint tmp;
+
+    tmpp = E; E = D; D = tmpp;
+    tmp = ABCE; ABCE = ABCD; ABCD = tmp;
+    reversed = TRUE;
+  }
+  if (ABCE < 0 || ABCD > 0)
+    return -1.;
+  ADCE = gts_point_orientation_3d_sos (A, D, C, E);
+  if (ADCE < 0)
+    return -1.;
+  ABDE = gts_point_orientation_3d_sos (A, B, D, E);
+  if (ABDE < 0)
+    return -1.;
+  BCDE = gts_point_orientation_3d_sos (B, C, D, E);
+  if (BCDE < 0)
+    return -1.;
+  *inside = reversed ? (ABCD < 0) : (ABCE < 0);
+  a = gts_point_orientation_3d (A, B, C, E);
+  b = gts_point_orientation_3d (A, B, C, D);
+  if (a != b)
+    return reversed ? 1. - a/(a - b) : a/(a - b);
+  /* D and E are contained within ABC */
+  g_assert (a == 0.);
+  return 0.5;
+}
+
+static void triangle_face_intersection (GtsTriangle * t, GfsSegment * I)
+{
+  gboolean ins;
+  gdouble x = segment_triangle_intersection (I->E, I->D, t, &ins);
+  
+  if (x != -1.) {
+    I->x += x; I->n++;
+    I->inside += ins ? 1 : -1;
+  }
+}
+
+static GtsPoint segment_intersection (GfsSegment * I)
+{
+  GtsPoint p;
+  p.x = I->E->x + I->x*(I->D->x - I->E->x);
+  p.y = I->E->y + I->x*(I->D->y - I->E->y);
+  p.z = I->E->z + I->x*(I->D->z - I->E->z);
+  /* lines below just to prevent compiler warnings about uninitialised fields */
+  p.object.flags = 0;
+  p.object.reserved = NULL;
+  p.object.klass = NULL;
+  return p;
+}
+
+static guint surface_segment_intersection (GfsGenericSurface * s1,
+					   FttCell * cell,
+					   GfsSegment * I)
+{
+  GfsSurface * s = GFS_SURFACE (s1);
+
+  I->n = 0;
+  I->x = 0.;
+  I->inside = 0;
+
+  if (s->s)
+    gts_surface_foreach_face (s->s, (GtsFunc) triangle_face_intersection, I);
+  else {
+    gdouble vE = gfs_surface_implicit_value (s, *I->E);
+    gdouble vD = gfs_surface_implicit_value (s, *I->D);
+    
+    if ((vE > 0. && vD <= 0.) || (vE <= 0. && vD > 0.)) {
+      I->n = 1;
+      I->inside = vE > 0. ? -1 : 1;
+
+      /* secant-bisection root-finding */
+      gdouble t, t1, t2, v1, v2;
+      if (vE > vD) {
+	v1 = vD; t1 = 1.;
+	v2 = vE; t2 = 0.;
+      }
+      else {
+	v1 = vE; t1 = 0.;
+	v2 = vD; t2 = 1.;
+      }
+      I->x = (v1*t2 - v2*t1)/(v1 - v2);
+      guint n = 0;
+      gint side = 0;
+      do {
+	t = I->x;
+	gdouble v = gfs_surface_implicit_value (s, segment_intersection (I));
+	if (v < 0.) {
+	  v1 = v; t1 = I->x;
+	  if (side == -1) v2 /= 2.;
+	  side = -1;
+	}
+	else {
+	  v2 = v; t2 = I->x;
+	  if (side == +1) v1 /= 2.;
+	  side = +1;
+	}
+	if (v2 > v1)
+	  I->x = (v1*t2 - v2*t1)/(v1 - v2);
+	n++;
+      }
+      while (fabs (t - I->x) > 1e-5 && n < 100);
+      if (fabs (t - I->x) > 1e-5)
+	g_warning ("gfs_surface_segment_intersection(): convergence could not be reached\n"
+		   "after %d iterations, error is %g", n, fabs (t - I->x));
+    }
+  }
+  return I->n;
+}
+
+static void surface_normal (GtsTriangle * t, GtsVector n)
+{
+  GtsVector m;
+  gts_triangle_normal (t, &m[0], &m[1], &m[2]);
+  n[0] -= m[0];
+  n[1] -= m[1];
+  n[2] -= m[2];
+}
+
+static void surface_segment_normal (GfsGenericSurface * s1,
+				    FttCell * cell,
+				    GfsSegment * I,
+				    GtsVector n)
+{
+  GfsSurface * s = GFS_SURFACE (s1);
+  if (s->s) {
+    n[0] = n[1] = n[2] = 0.;
+    gts_surface_foreach_face (s->s, (GtsFunc) surface_normal, n);
+  }
+  else {
+    FttComponent c;
+    GtsPoint p = segment_intersection (I);
+    for (c = 0; c < FTT_DIMENSION; c++) {
+      GtsPoint p1 = p;
+      (&p1.x)[c] -= 1e-4;
+      gdouble v1 = gfs_surface_implicit_value (s, p1);
+      (&p1.x)[c] += 2e-4;
+      gdouble v2 = gfs_surface_implicit_value (s, p1);
+      n[c] = v2 - v1;
+    }
+  }
+}
+
+static void add_tetrahedron_volume (GtsTriangle * t, gpointer * data)
+{
+  GtsPoint * p = data[0];
+  GtsVertex * v1, * v2, * v3;
+  gdouble * vol = data[1];
+  gts_triangle_vertices (t, &v1, &v2, &v3);
+  *vol += gts_point_orientation_3d (GTS_POINT (v1), GTS_POINT (v2), GTS_POINT (v3), p);
+}
+
+static gint point_is_inside_surface (GfsGenericSurface * s1, FttVector * p)
+{
+  GfsSurface * s = GFS_SURFACE (s1);
+  GtsPoint q;
+  q.x = p->x; q.y = p->y; q.z = p->z;
+
+  if (s->s) {
+    gdouble vol = 0.;
+    gpointer data[2];
+    data[0] = &q;
+    data[1] = &vol;
+    gts_surface_foreach_face (s->s, (GtsFunc) add_tetrahedron_volume, data);
+    fprintf (stderr, "vol: %g\n", vol);
+    return vol > 0. ? -1 : 1;
+  }
+  else {
+    gdouble v = gfs_surface_implicit_value (s, q);
+    return v == 0. ? 0 : v < 0. ? -1 : 1;
+  }
+  return 0;
+}
+
+static void gfs_surface_class_init (GtsObjectClass * klass)
+{
+  klass->read = surface_read;
+  klass->write = surface_write;
+  klass->destroy = surface_destroy;
+
+  GFS_GENERIC_SURFACE_CLASS (klass)->cell_is_cut = cell_is_cut;
+  GFS_GENERIC_SURFACE_CLASS (klass)->segment_intersection = surface_segment_intersection;
+  GFS_GENERIC_SURFACE_CLASS (klass)->segment_normal = surface_segment_normal;
+  GFS_GENERIC_SURFACE_CLASS (klass)->point_is_inside = point_is_inside_surface;
+}
+
+static void gfs_surface_init (GfsSurface * s)
+{
+  s->scale[0] = 1.; s->scale[1] = 1.; s->scale[2] = 1.;
+  s->flip = FALSE;
+}
+
+GfsGenericSurfaceClass * gfs_surface_class (void)
+{
+  static GfsGenericSurfaceClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_surface_info = {
+      "GfsSurface",
+      sizeof (GfsSurface),
+      sizeof (GfsGenericSurfaceClass),
+      (GtsObjectClassInitFunc) gfs_surface_class_init,
+      (GtsObjectInitFunc) gfs_surface_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_surface_class ()), 
+				  &gfs_surface_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_surface_implicit_value:
+ * @s: an (implicit) #GfsSurface.
+ * @p: a #GtsPoint.
+ *
+ * Returns: the value of the implicit surface a location @p.
+ */
+gdouble gfs_surface_implicit_value (GfsSurface * s, GtsPoint p)
+{
+  g_return_val_if_fail (s != NULL, 0.);
+  g_return_val_if_fail (s->f != NULL, 0.);
+
+  if (s->m)
+    gts_point_transform (&p, s->m);
+  return (s->flip ? -1. : 1.)*(gfs_function_spatial_value (s->f, (FttVector *)&p.x)
+			       /* fixme?? */ + 1e-6);
+}
diff --git a/src/surface.h b/src/surface.h
new file mode 100644
index 0000000..d6fdae1
--- /dev/null
+++ b/src/surface.h
@@ -0,0 +1,145 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __SURFACE_H__
+#define __SURFACE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gts.h>
+#include "ftt.h"
+
+/* GfsGenericSurface: Header */
+
+typedef GtsObject GfsGenericSurface;
+
+typedef struct {
+  GtsPoint * E, * D;
+  gdouble x;
+  guint n;
+  gint inside;
+} GfsSegment;
+
+typedef struct _GfsGenericSurfaceClass    GfsGenericSurfaceClass;
+
+struct _GfsGenericSurfaceClass {
+  /*< private >*/
+  GtsObjectClass parent_class;
+
+  /*< public >*/
+  GfsGenericSurface * (* cell_is_cut)          (FttCell * cell,
+						GfsGenericSurface * s,
+						gboolean flatten,
+						gint maxlevel);
+  guint               (* segment_intersection) (GfsGenericSurface * s,
+						FttCell * cell,
+						GfsSegment * I);
+  void                (* segment_normal)       (GfsGenericSurface * s,
+						FttCell * cell,
+						GfsSegment * I,
+						GtsVector n);
+  gint                (* point_is_inside)      (GfsGenericSurface * s,
+						FttVector * p);
+};
+
+#define GFS_GENERIC_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
+					         GtsObject,\
+					         gfs_generic_surface_class ())
+#define GFS_GENERIC_SURFACE_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsGenericSurfaceClass,\
+						 gfs_generic_surface_class())
+#define GFS_IS_GENERIC_SURFACE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_generic_surface_class ()))
+
+GfsGenericSurfaceClass * gfs_generic_surface_class  (void);
+guint              gfs_surface_segment_intersection (GfsGenericSurface * s,
+						     FttCell * cell,
+						     GfsSegment * I);
+void               gfs_surface_segment_normal       (GfsGenericSurface * s,
+						     FttCell * cell,
+						     GfsSegment * I,
+						     GtsVector n);
+gint               gfs_surface_point_is_inside      (GfsGenericSurface * s,
+						     FttVector * p);
+GfsGenericSurface *      gfs_cell_is_cut (FttCell * cell,
+					  GfsGenericSurface * s,
+					  gboolean flatten,
+					  gint maxlevel);
+typedef void       (* FttCellTraverseCutFunc) (FttCell * cell,
+					       GfsGenericSurface * s,
+					       gpointer data);
+void               gfs_cell_traverse_cut       (FttCell * root,
+						GfsGenericSurface * s,
+						FttTraverseType order,
+						FttTraverseFlags flags,
+						FttCellTraverseCutFunc func,
+						gpointer data);
+void               gfs_cell_traverse_cut_2D    (FttCell * root,
+						GfsGenericSurface * s,
+						FttTraverseType order,
+						FttTraverseFlags flags,
+						FttCellTraverseCutFunc func,
+						gpointer data);
+void               gfs_generic_surface_read    (GfsGenericSurface * s, 
+						gpointer sim,
+						GtsFile * fp);
+void               gfs_generic_surface_write   (GfsGenericSurface * s,
+						gpointer sim,
+						FILE * fp);
+
+/* GfsSurface: Header */
+
+typedef struct _GfsSurface         GfsSurface;
+
+struct _GfsSurface {
+  /*< private >*/
+  GtsObject parent;
+  GtsVector rotate, scale, translate;
+  gboolean flip;
+  GfsFunction * f;
+  GtsMatrix * m;
+
+  /*< public >*/
+  GtsSurface * s;
+  gboolean twod;
+};
+
+#define GFS_SURFACE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSurface,\
+					         gfs_surface_class ())
+#define GFS_IS_SURFACE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_surface_class ()))
+
+GfsGenericSurfaceClass *   gfs_surface_class          (void);
+gdouble            gfs_surface_implicit_value (GfsSurface * s, 
+					       GtsPoint p);
+void               gfs_surface_transformation (GtsSurface * surface, 
+					       GtsVector rotate,
+					       GtsVector translate, 
+					       GtsVector scale,
+					       gboolean flip,
+					       GtsMatrix ** matrix);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SURFACE_H__ */
diff --git a/src/tension.c b/src/tension.c
new file mode 100644
index 0000000..44e38ac
--- /dev/null
+++ b/src/tension.c
@@ -0,0 +1,859 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "tension.h"
+#include "vof.h"
+#include "levelset.h"
+
+/* GfsSourceTensionGeneric: Object */
+
+static void gfs_source_tension_generic_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_SOURCE_TENSION_GENERIC (o)->sigma));
+  (* GTS_OBJECT_CLASS (gfs_source_tension_generic_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_source_tension_generic_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceTensionGeneric * s = GFS_SOURCE_TENSION_GENERIC (*o);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+
+  (* GTS_OBJECT_CLASS (gfs_source_tension_generic_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a variable (C)");
+    return;
+  }
+  if ((s->c = gfs_variable_from_name (domain->variables, fp->token->str)) == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  gfs_function_read (s->sigma, domain, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  gfs_function_set_units (s->sigma, 3.);
+}
+
+static void gfs_source_tension_generic_write (GtsObject * o, FILE * fp)
+{
+  GfsSourceTensionGeneric * t = GFS_SOURCE_TENSION_GENERIC (o);
+  (* GTS_OBJECT_CLASS (gfs_source_tension_generic_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s", t->c->name);
+  gfs_function_write (t->sigma, fp);
+}
+
+typedef struct {
+  gdouble amin, amax;
+  guint depth;
+  gdouble sigma;
+  GfsSourceTensionGeneric * t;
+  GfsFunction * alpha;
+  GfsVariable * c;
+} StabilityParams;
+
+static void interface_level (FttCell * cell, StabilityParams * p)
+{
+  guint level = ftt_cell_level (cell);
+  if (level > p->depth &&
+      GFS_VALUE (cell, p->c) > 1e-3 && 
+      GFS_VALUE (cell, p->c) < 1. - 1.e-3) {
+    p->depth = level;
+    /* fixme: this may not work for a variable surface tension coefficient */
+    p->sigma = gfs_function_value (p->t->sigma, cell);
+  }
+}
+
+static void min_max_alpha (FttCell * cell, StabilityParams * p)
+{
+  interface_level (cell, p);
+  if (p->alpha) {
+    gdouble a = gfs_function_value (p->alpha, cell);
+    if (a < p->amin) p->amin = a;
+    if (a > p->amax) p->amax = a;
+  }
+}
+
+static gdouble gfs_source_tension_generic_stability (GfsSourceGeneric * s,
+						     GfsSimulation * sim)
+{
+  GfsSourceTensionGeneric * t = GFS_SOURCE_TENSION_GENERIC (s);
+  gdouble h;
+  StabilityParams p = { G_MAXDOUBLE, -G_MAXDOUBLE, 0 };
+
+  p.alpha = sim->physical_params.alpha;
+  p.c = t->c;
+  p.t = t;
+  p.sigma = 0.;
+  gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) min_max_alpha, &p);
+  if (p.sigma == 0.) /* no interface */
+    return G_MAXDOUBLE;
+  h = ftt_level_size (p.depth);
+  if (p.alpha) {
+    gdouble rhom = (1./p.amin + 1./p.amax)/2.;
+    return sqrt (rhom*h*h*h/(M_PI*p.sigma));
+  }
+  else
+    return sqrt (h*h*h/(M_PI*p.sigma));
+}
+
+static void gfs_source_tension_generic_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_source_tension_generic_destroy;
+  GTS_OBJECT_CLASS (klass)->read =    gfs_source_tension_generic_read;
+  GTS_OBJECT_CLASS (klass)->write =   gfs_source_tension_generic_write;
+  klass->stability =                  gfs_source_tension_generic_stability;
+}
+
+static void gfs_source_tension_generic_init (GfsSourceTensionGeneric * t)
+{
+  t->sigma = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsSourceGenericClass * gfs_source_tension_generic_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_tension_generic_info = {
+      "GfsSourceTensionGeneric",
+      sizeof (GfsSourceTensionGeneric),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_tension_generic_class_init,
+      (GtsObjectInitFunc) gfs_source_tension_generic_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_velocity_class ()),
+			    &gfs_source_tension_generic_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceTensionCSS: Object */
+
+static void gfs_source_tension_css_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceTensionCSS * s = GFS_SOURCE_TENSION_CSS (*o);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  FttComponent c;
+
+  (* GTS_OBJECT_CLASS (gfs_source_tension_css_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    static gchar * name[3] = {"_Tx", "_Ty", "_Tz"};
+    if ((s->t[c] = gfs_variable_from_name (domain->variables, name[c])) == NULL)
+      s->t[c] = gfs_domain_add_variable (domain, name[c], NULL);
+  }
+}
+
+static void foreach_cell_normal (FttCell * cell, GfsSourceTensionCSS * s)
+{
+  FttVector n;
+  gdouble nn = 0.;
+  gdouble sigh = gfs_function_value (GFS_SOURCE_TENSION_GENERIC (s)->sigma, cell)
+    /ftt_cell_size (cell);
+  FttComponent c;
+
+  gfs_youngs_gradient (cell, GFS_SOURCE_TENSION_GENERIC (s)->c, &n);
+  for (c = 0; c < FTT_DIMENSION; c++)
+    nn += (&n.x)[c]*(&n.x)[c];
+  nn = sqrt (nn + 1e-50);
+  GFS_VARIABLE (cell, s->g[0]->i) = sigh*n.x*n.x/nn;
+  GFS_VARIABLE (cell, s->g[1]->i) = sigh*n.y*n.y/nn;
+  GFS_VARIABLE (cell, s->g[2]->i) = sigh*n.x*n.y/nn;
+}
+
+static void foreach_cell_tension_css (FttCell * cell, GfsSourceTensionCSS * s)
+{
+  gdouble h = ftt_cell_size (cell);
+  FttVector nx, ny, nxy;
+  GfsSimulation * sim = gfs_object_simulation (s);
+  gdouble alpha = sim->physical_params.alpha ? 
+    gfs_function_value (sim->physical_params.alpha, cell) : 1.;
+
+  gfs_youngs_gradient (cell, s->g[0], &nx);
+  gfs_youngs_gradient (cell, s->g[1], &ny);
+  gfs_youngs_gradient (cell, s->g[2], &nxy);
+
+  GFS_VARIABLE (cell, s->t[0]->i) = alpha*(ny.x - nxy.y)/h;
+  GFS_VARIABLE (cell, s->t[1]->i) = alpha*(nx.y - nxy.x)/h;
+}
+
+static gboolean gfs_source_tension_css_event (GfsEvent * event, 
+					      GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_source_tension_css_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsSourceTensionCSS * s = GFS_SOURCE_TENSION_CSS (event);
+    guint i;
+
+#if (!FTT_2D)
+    g_assert_not_implemented ();
+#endif
+
+    for (i = 0; i < 3; i++)
+      s->g[i] = gfs_temporary_variable (GFS_DOMAIN (sim));
+
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim),
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) foreach_cell_normal, event);
+    /* fixme: boundary conditions for normal */
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) foreach_cell_tension_css, event);
+    for (i = 0; i < 3; i++)
+      gts_object_destroy (GTS_OBJECT (s->g[i]));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static gdouble gfs_source_tension_css_value (GfsSourceGeneric * s, 
+					     FttCell * cell,
+					     GfsVariable * v)
+{
+  return GFS_VARIABLE (cell, GFS_SOURCE_TENSION_CSS (s)->t[v->component]->i);
+}
+
+static void gfs_source_tension_css_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_source_tension_css_read;
+  GFS_EVENT_CLASS (klass)->event = gfs_source_tension_css_event;
+}
+
+static void gfs_source_tension_css_init (GfsSourceGeneric * s)
+{
+  s->centered_value = gfs_source_tension_css_value;
+}
+
+GfsSourceGenericClass * gfs_source_tension_css_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_tension_css_info = {
+      "GfsSourceTensionCSS",
+      sizeof (GfsSourceTensionCSS),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_tension_css_class_init,
+      (GtsObjectInitFunc) gfs_source_tension_css_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_tension_generic_class ()),
+			    &gfs_source_tension_css_info);
+  }
+
+  return klass;
+}
+
+/* GfsSourceTension: Object */
+
+static void gfs_source_tension_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSourceTension * s = GFS_SOURCE_TENSION (*o);
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+
+  (* GTS_OBJECT_CLASS (gfs_source_tension_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a variable (Kappa)");
+    return;
+  }
+  if ((s->k = gfs_variable_from_name (domain->variables, fp->token->str)) == NULL) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (GFS_IS_VARIABLE_POSITION (s->k))
+    gfs_function_set_units (GFS_SOURCE_TENSION_GENERIC (s)->sigma, 1.);
+}
+
+static void gfs_source_tension_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_source_tension_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s", GFS_SOURCE_TENSION (o)->k->name);
+}
+
+static gdouble gfs_source_tension_stability (GfsSourceGeneric * s,
+					     GfsSimulation * sim)
+{
+  if (GFS_IS_VARIABLE_POSITION (GFS_SOURCE_TENSION (s)->k)) {
+    /* reduced gravity */
+    StabilityParams p = { G_MAXDOUBLE, -G_MAXDOUBLE, 0 };
+    p.c = GFS_SOURCE_TENSION_GENERIC (s)->c;
+    p.t = GFS_SOURCE_TENSION_GENERIC (s);
+    p.sigma = 0.;
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) interface_level, &p);
+    return p.sigma > 0. ? sqrt (ftt_level_size (p.depth)/fabs (p.sigma)) : G_MAXDOUBLE;
+  }
+  else 
+    /* surface tension */
+    return gfs_source_tension_generic_stability (s, sim);
+}
+
+static void gfs_source_tension_class_init (GfsSourceGenericClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read =       gfs_source_tension_read;
+  GTS_OBJECT_CLASS (klass)->write =      gfs_source_tension_write;
+  klass->stability =                     gfs_source_tension_stability;
+}
+
+GfsSourceGenericClass * gfs_source_tension_class (void)
+{
+  static GfsSourceGenericClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_source_tension_info = {
+      "GfsSourceTension",
+      sizeof (GfsSourceTension),
+      sizeof (GfsSourceGenericClass),
+      (GtsObjectClassInitFunc) gfs_source_tension_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = 
+      gts_object_class_new (GTS_OBJECT_CLASS (gfs_source_tension_generic_class ()),
+			    &gfs_source_tension_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableCurvature: object */
+
+static void variable_curvature_destroy (GtsObject * o)
+{
+  if (GFS_VARIABLE_CURVATURE (o)->kmax)
+    gts_object_destroy (GTS_OBJECT (GFS_VARIABLE_CURVATURE (o)->kmax));
+
+  (* GTS_OBJECT_CLASS (gfs_variable_curvature_class ())->parent_class->destroy) (o);
+}
+
+static void curvature_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  guint n;
+
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++)
+    if (child.c[n])
+      GFS_VARIABLE (child.c[n], v->i) = GFS_VARIABLE (parent, v->i);
+}
+
+static void curvature_fine_coarse (FttCell * parent, GfsVariable * v)
+{
+  FttCellChildren child;
+  gdouble val = 0., sa = 0.;
+  guint i;
+
+  ftt_cell_children (parent, &child);
+  for (i = 0; i < FTT_CELLS; i++)
+    if (child.c[i] && GFS_VARIABLE (child.c[i], v->i) < G_MAXDOUBLE) {
+      val += GFS_VARIABLE (child.c[i], v->i);
+      sa += 1.;
+    }
+  if (sa > 0.)
+    GFS_VARIABLE (parent, v->i) = val/sa;
+  else
+    GFS_VARIABLE (parent, v->i) = G_MAXDOUBLE;
+}
+
+static void variable_curvature_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsVariableCurvature * v = GFS_VARIABLE_CURVATURE (*o);
+  GfsDomain * domain;
+
+  (* GTS_OBJECT_CLASS (gfs_variable_curvature_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (fraction or distance)");
+    return;
+  }
+  domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (!(v->f = gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  g_free (GFS_VARIABLE1 (v)->description);
+  GFS_VARIABLE1 (v)->description = NULL;
+  if (GFS_IS_VARIABLE_TRACER (v->f)) {
+    if (!GFS_IS_VARIABLE_TRACER_VOF (v->f)) {
+       gts_file_error (fp, "variable `%s' is not a VOF tracer", fp->token->str);
+       return;
+    }
+    GFS_VARIABLE1 (v)->description = g_strjoin (" ", 
+						"Curvature of the interface defined by tracer",
+						v->f->name, NULL);
+    gts_file_next_token (fp);
+    if (fp->type == GTS_STRING) {
+      v->kmax = gfs_domain_get_or_add_variable (domain, fp->token->str, "Maximum curvature");
+      if (v->kmax) {
+	v->kmax->coarse_fine = curvature_coarse_fine;
+	v->kmax->fine_coarse = curvature_fine_coarse;
+	gts_file_next_token (fp);
+      }
+      else if (!GFS_IS_VARIABLE_POSITION (v)) {
+	gts_file_error (fp, "`%s' is a reserved variable name", fp->token->str);
+	return;
+      }
+    }
+  }
+  else if (GFS_IS_VARIABLE_DISTANCE (v->f)) {
+    GFS_VARIABLE1 (v)->description = g_strjoin (" ", 
+						"Curvature of the interface defined by distance",
+						v->f->name, NULL); 
+    gts_file_next_token (fp);
+  }
+  else {
+    gts_file_error (fp, "variable `%s' is neither a tracer nor a distance", fp->token->str);
+    return;
+  }
+  GFS_VARIABLE1 (v)->units = -1.;
+  if (v->kmax)
+    v->kmax->units = -1.;
+}
+
+static void variable_curvature_write (GtsObject * o, FILE * fp)
+{
+  GfsVariableCurvature * v = GFS_VARIABLE_CURVATURE (o);
+
+  (* GTS_OBJECT_CLASS (gfs_variable_curvature_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s", v->f->name);
+  if (v->kmax)
+    fprintf (fp, " %s", v->kmax->name);
+}
+
+static void height_curvature (FttCell * cell, GfsVariable * v)
+{
+  GfsVariable * t = GFS_VARIABLE_CURVATURE (v)->f;
+  GfsVariable * kmax = GFS_VARIABLE_CURVATURE (v)->kmax;
+  gdouble f = GFS_VALUE (cell, t);
+
+  if (GFS_IS_FULL (f)) {
+    GFS_VALUE (cell, v) = G_MAXDOUBLE;
+    if (kmax)
+      GFS_VALUE (cell, kmax) = G_MAXDOUBLE;
+  }
+  else {
+    if (kmax) {
+      gdouble k;
+      GFS_VALUE (cell, v) = gfs_height_curvature (cell, GFS_VARIABLE_TRACER_VOF (t), &k);
+      GFS_VALUE (cell, kmax) = k;
+    }
+    else
+      GFS_VALUE (cell, v) = gfs_height_curvature (cell, GFS_VARIABLE_TRACER_VOF (t), NULL);
+  }
+}
+
+static void fit_curvature (FttCell * cell, GfsVariable * v)
+{
+  GfsVariable * t = GFS_VARIABLE_CURVATURE (v)->f;
+  gdouble f = GFS_VALUE (cell, t);
+
+  if (!GFS_IS_FULL (f) && GFS_VALUE (cell, v) == G_MAXDOUBLE) {
+    GfsVariable * kmax = GFS_VARIABLE_CURVATURE (v)->kmax;
+    if (kmax) {
+      gdouble k;
+      GFS_VALUE (cell, v) = gfs_fit_curvature (cell, GFS_VARIABLE_TRACER_VOF (t), &k);
+      GFS_VALUE (cell, kmax) = k;
+    }
+    else
+      GFS_VALUE (cell, v) = gfs_fit_curvature (cell, GFS_VARIABLE_TRACER_VOF (t), NULL);    
+  }
+}
+
+typedef struct {
+  GfsVariable * v, * f, * tmp;
+} DiffuseParms;
+
+#define FMIN 0.01
+
+static void diffuse_kmax (FttCell * cell, DiffuseParms * p)
+{
+  gdouble f = GFS_VARIABLE (cell, p->f->i);
+  if (GFS_VARIABLE (cell, p->v->i) < G_MAXDOUBLE && f*(1. - f) > FMIN*(1. - FMIN))
+    GFS_VARIABLE (cell, p->tmp->i) = GFS_VARIABLE (cell, p->v->i);
+  else {
+    FttCellNeighbors neighbor;
+    gdouble sa = 0., s = 0.;
+    FttDirection d;
+
+    ftt_cell_neighbors (cell, &neighbor);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (neighbor.c[d] && GFS_VARIABLE (neighbor.c[d], p->v->i) < G_MAXDOUBLE) {
+	gdouble f = GFS_VARIABLE (neighbor.c[d], p->f->i);
+	if (f*(1. - f) > FMIN*(1. - FMIN)) {
+	  f *= 1. - f;
+	  s += f*GFS_VARIABLE (neighbor.c[d], p->v->i);
+	  sa += f;
+	}
+      }
+    if (sa > 0.)
+      GFS_VARIABLE (cell, p->tmp->i) = s/sa;
+    else
+      GFS_VARIABLE (cell, p->tmp->i) = GFS_VARIABLE (cell, p->v->i);
+  }
+}
+
+static void diffuse (FttCell * cell, DiffuseParms * p)
+{
+  if (GFS_VARIABLE (cell, p->v->i) < G_MAXDOUBLE)
+    GFS_VARIABLE (cell, p->tmp->i) = GFS_VARIABLE (cell, p->v->i);
+  else {
+    FttCellNeighbors neighbor;
+    gdouble sa = 0., s = 0.;
+    FttDirection d;
+
+    ftt_cell_neighbors (cell, &neighbor);
+    for (d = 0; d < FTT_NEIGHBORS; d++)
+      if (neighbor.c[d] && GFS_VARIABLE (neighbor.c[d], p->v->i) < G_MAXDOUBLE) {
+	s += GFS_VARIABLE (neighbor.c[d], p->v->i);
+	sa += 1.;
+      }
+    if (sa > 0.)
+      GFS_VARIABLE (cell, p->tmp->i) = s/sa;
+    else
+      GFS_VARIABLE (cell, p->tmp->i) = G_MAXDOUBLE;
+  }
+}
+
+static void variable_curvature_diffuse (GfsVariable * v, GfsVariable * f, 
+					GfsSimulation * sim, guint n)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  FttCellTraverseFunc diff = f ? (FttCellTraverseFunc) diffuse_kmax : (FttCellTraverseFunc) diffuse;
+  DiffuseParms p;
+  p.v = v;
+  p.f = f;
+  p.tmp = gfs_temporary_variable (domain);
+
+  while (n--) {
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1, diff, &p);
+    gfs_variables_swap (p.v, p.tmp);
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) p.v->fine_coarse, p.v);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, p.v);
+  }
+
+  gts_object_destroy (GTS_OBJECT (p.tmp));  
+}
+
+static void variable_curvature_from_fraction (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariable * kmax = GFS_VARIABLE_CURVATURE (event)->kmax;
+
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) height_curvature, event);
+  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) GFS_VARIABLE1 (event)->fine_coarse, event);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, GFS_VARIABLE1 (event));
+  if (kmax) {
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) kmax->fine_coarse, kmax);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, kmax);
+    variable_curvature_diffuse (kmax, GFS_VARIABLE_CURVATURE (event)->f, sim, 1);
+  }
+  variable_curvature_diffuse (GFS_VARIABLE1 (event), NULL, sim, 1);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) fit_curvature, event);
+  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) GFS_VARIABLE1 (event)->fine_coarse, event);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, GFS_VARIABLE1 (event));
+  if (kmax) {
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) kmax->fine_coarse, kmax);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, kmax);
+    variable_curvature_diffuse (kmax, GFS_VARIABLE_CURVATURE (event)->f, sim, 1);
+  }
+  variable_curvature_diffuse (GFS_VARIABLE1 (event), NULL, sim, 1);
+}
+
+static void normal (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** nv = data[0];
+  GfsVariable * d = GFS_VARIABLE_CURVATURE (data[1])->f;
+  GtsVector n = { 0., 0., 0. };
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    n[c] = gfs_center_gradient (cell, c, d->i);
+  gts_vector_normalize (n);
+  for (c = 0; c < FTT_DIMENSION; c++)
+    GFS_VARIABLE (cell, nv[c]->i) = n[c];
+}
+
+static void distance_curvature (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** nv = data[0];
+  gdouble kappa = 0.;
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++)
+    kappa += gfs_center_gradient (cell, c, nv[c]->i);
+  GFS_VALUE (cell, nv[FTT_DIMENSION]) = kappa/ftt_cell_size (cell);
+}
+
+static void interface_curvature (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[1];
+  GfsVariableCurvature * k = GFS_VARIABLE_CURVATURE (v);
+  gdouble f = GFS_VARIABLE (cell, GFS_VARIABLE_DISTANCE (k->f)->v->i);
+
+  if (GFS_IS_FULL (f))
+    GFS_VARIABLE (cell, v->i) = G_MAXDOUBLE;
+  else {
+    GfsVariable ** nv = data[0];
+    gdouble h = ftt_cell_size (cell)/2.;
+    FttCell * target = cell;
+    FttComponent c;
+    FttVector p;
+
+    ftt_cell_pos (cell, &p);
+    for (c = 0; c < FTT_DIMENSION; c++) {
+      gdouble delta = GFS_VARIABLE (cell, k->f->i)*GFS_VARIABLE (cell, nv[c]->i);
+      (&p.x)[c] -= delta;
+      if (fabs (delta) > h)
+	target = NULL;
+    }
+    if (!target)
+      target = gfs_domain_locate (v->domain, p, -1, NULL);
+    GFS_VARIABLE (cell, v->i) = gfs_interpolate (target, p, nv[FTT_DIMENSION]);
+  }
+}
+
+static void variable_curvature_from_distance (GfsEvent * event, GfsSimulation * sim)
+{
+  GfsVariable * n[FTT_DIMENSION + 1];
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  gpointer data[2];
+  FttComponent c;
+
+  if (GFS_IS_AXI (sim))
+    g_assert_not_implemented ();
+
+  for (c = 0; c < FTT_DIMENSION + 1; c++)
+    n[c] = gfs_temporary_variable (domain);
+  gfs_variable_set_vector (n, FTT_DIMENSION);
+  data[0] = n;
+  data[1] = event;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) normal, data);
+  for (c = 0; c < FTT_DIMENSION; c++)
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, n[c]);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) distance_curvature, data);
+  gfs_domain_copy_bc (domain, FTT_TRAVERSE_LEAFS, -1, 
+		      GFS_VARIABLE1 (event), n[FTT_DIMENSION]);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) interface_curvature, data);
+  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) GFS_VARIABLE1 (event)->fine_coarse, event);
+  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, GFS_VARIABLE1 (event));
+  for (c = 0; c < FTT_DIMENSION + 1; c++)
+    gts_object_destroy (GTS_OBJECT (n[c]));
+
+  variable_curvature_diffuse (GFS_VARIABLE1 (event), NULL, sim, 2);
+}
+
+static gboolean variable_curvature_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_curvature_class ())->parent_class)->event)
+      (event, sim)) {
+    if (GFS_IS_VARIABLE_TRACER (GFS_VARIABLE_CURVATURE (event)->f))
+      variable_curvature_from_fraction (event, sim);
+    else /* distance */
+      variable_curvature_from_distance (event, sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_curvature_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = variable_curvature_destroy;
+  klass->read = variable_curvature_read;
+  klass->write = variable_curvature_write;
+  GFS_EVENT_CLASS (klass)->event = variable_curvature_event;
+}
+
+static void variable_curvature_init (GfsVariable * v)
+{
+  v->coarse_fine = curvature_coarse_fine;
+  v->fine_coarse = curvature_fine_coarse;
+  v->units = -1.;
+}
+
+GfsVariableClass * gfs_variable_curvature_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_curvature_info = {
+      "GfsVariableCurvature",
+      sizeof (GfsVariableCurvature),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_curvature_class_init,
+      (GtsObjectInitFunc) variable_curvature_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_curvature_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariablePosition: object */
+
+static void variable_position_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsVariablePosition * v = GFS_VARIABLE_POSITION (*o);
+
+  (* GTS_OBJECT_CLASS (gfs_variable_position_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (component)");
+    return;
+  }
+  if (!strcmp (fp->token->str, "x"))
+    v->c = FTT_X;
+  else if (!strcmp (fp->token->str, "y"))
+    v->c = FTT_Y;
+#if !FTT_2D
+  else if (!strcmp (fp->token->str, "z"))
+    v->c = FTT_Z;
+#endif /* 3D */
+  else {
+    gts_file_error (fp, "`%s' is not a valid component", fp->token->str);
+    return;
+  }
+  if (GFS_VARIABLE1 (v)->description)
+    g_free (GFS_VARIABLE1 (v)->description);
+  GFS_VARIABLE1 (v)->description = g_strjoin (" ", fp->token->str,
+					      "coordinate of the interface defined by tracer",
+					      GFS_VARIABLE_CURVATURE (v)->f->name, NULL);
+  GFS_VARIABLE1 (v)->units = 1.;
+  gts_file_next_token (fp);
+  if (fp->type != '\n')
+    /* fixme: mapping? */
+    v->ref = gfs_read_constant (fp, gfs_object_simulation (*o));
+}
+
+static void variable_position_write (GtsObject * o, FILE * fp)
+{
+  GfsVariablePosition * v = GFS_VARIABLE_POSITION (o);
+
+  (* GTS_OBJECT_CLASS (gfs_variable_position_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s", v->c == FTT_X ? "x" : v->c == FTT_Y ? "y" : "z");
+  if (v->ref != 0.)
+    fprintf (fp, " %g", v->ref);
+}
+
+static void position (FttCell * cell, GfsVariable * v)
+{
+  FttVector p;
+
+  if (gfs_vof_center (cell, GFS_VARIABLE_TRACER_VOF (GFS_VARIABLE_CURVATURE (v)->f), &p))
+    GFS_VARIABLE (cell, v->i) = (&p.x)[GFS_VARIABLE_POSITION (v)->c] - 
+      GFS_VARIABLE_POSITION (v)->ref;
+  else
+    GFS_VARIABLE (cell, v->i) = G_MAXDOUBLE;
+}
+
+static gboolean variable_position_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    
+    gfs_domain_timer_start (domain, "variable_position");
+    
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) position, event);
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) GFS_VARIABLE1 (event)->fine_coarse, event);
+    gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, GFS_VARIABLE1 (event));
+    
+    variable_curvature_diffuse (GFS_VARIABLE1 (event), NULL, sim, 2);
+    
+    gfs_domain_timer_stop (domain, "variable_position");
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_position_class_init (GtsObjectClass * klass)
+{
+  klass->read = variable_position_read;
+  klass->write = variable_position_write;
+  GFS_EVENT_CLASS (klass)->event = variable_position_event;
+}
+
+static void variable_position_init (GfsVariable * v)
+{
+  v->units = 1.;
+}
+
+GfsVariableClass * gfs_variable_position_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_position_info = {
+      "GfsVariablePosition",
+      sizeof (GfsVariablePosition),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_position_class_init,
+      (GtsObjectInitFunc) variable_position_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_curvature_class ()), 
+				  &gfs_variable_position_info);
+  }
+
+  return klass;
+}
diff --git a/src/tension.h b/src/tension.h
new file mode 100644
index 0000000..73b199e
--- /dev/null
+++ b/src/tension.h
@@ -0,0 +1,139 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __TENSION_H__
+#define __TENSION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "source.h"
+
+/* GfsSourceTensionGeneric: Header */
+
+typedef struct _GfsSourceTensionGeneric         GfsSourceTensionGeneric;
+
+struct _GfsSourceTensionGeneric {
+  /*< private >*/
+  GfsSourceVelocity parent;
+  
+  /*< public >*/
+  GfsVariable * c;
+  GfsFunction * sigma;
+};
+
+#define GFS_SOURCE_TENSION_GENERIC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceTensionGeneric,\
+					         gfs_source_tension_generic_class ())
+#define GFS_IS_SOURCE_TENSION_GENERIC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_tension_generic_class ()))
+
+GfsSourceGenericClass * gfs_source_tension_generic_class (void);
+
+/* GfsSourceTensionCSS: Header */
+
+typedef struct _GfsSourceTensionCSS         GfsSourceTensionCSS;
+
+struct _GfsSourceTensionCSS {
+  /*< private >*/
+  GfsSourceTensionGeneric parent;
+  GfsVariable * g[3];
+  
+  /*< public >*/
+  GfsVariable * t[FTT_DIMENSION];
+};
+
+#define GFS_SOURCE_TENSION_CSS(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceTensionCSS,\
+					         gfs_source_tension_css_class ())
+#define GFS_IS_SOURCE_TENSION_CSS(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_tension_css_class ()))
+
+GfsSourceGenericClass * gfs_source_tension_css_class (void);
+
+/* GfsSourceTension: Header */
+
+typedef struct _GfsSourceTension         GfsSourceTension;
+
+struct _GfsSourceTension {
+  /*< private >*/
+  GfsSourceTensionGeneric parent;
+  
+  /*< public >*/
+  GfsVariable * k;
+};
+
+#define GFS_SOURCE_TENSION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSourceTension,\
+					         gfs_source_tension_class ())
+#define GFS_IS_SOURCE_TENSION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_source_tension_class ()))
+
+GfsSourceGenericClass * gfs_source_tension_class        (void);
+void                    gfs_source_tension_coefficients (GfsSourceTension * s,
+							 GfsDomain * domain,
+							 GfsFunction * alpha);
+
+/* GfsVariableCurvature: header */
+
+typedef struct _GfsVariableCurvature                GfsVariableCurvature;
+
+struct _GfsVariableCurvature {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsVariable * f, * kmax;
+};
+
+#define GFS_VARIABLE_CURVATURE(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableCurvature,\
+					           gfs_variable_curvature_class ())
+#define GFS_IS_VARIABLE_CURVATURE(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_curvature_class ()))
+
+GfsVariableClass * gfs_variable_curvature_class  (void);
+
+/* GfsVariablePosition: header */
+
+typedef struct _GfsVariablePosition                GfsVariablePosition;
+
+struct _GfsVariablePosition {
+  /*< private >*/
+  GfsVariableCurvature parent;
+
+  /*< public >*/
+  FttComponent c;
+  gdouble ref;
+};
+
+#define GFS_VARIABLE_POSITION(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariablePosition,\
+					           gfs_variable_position_class ())
+#define GFS_IS_VARIABLE_POSITION(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_position_class ()))
+
+GfsVariableClass * gfs_variable_position_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TENSION_H__ */
diff --git a/src/timestep.c b/src/timestep.c
new file mode 100644
index 0000000..df568c8
--- /dev/null
+++ b/src/timestep.c
@@ -0,0 +1,1053 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "timestep.h"
+#include "source.h"
+#include "solid.h"
+#include "tension.h"
+
+static void reset_cell_gradients (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** g = data[0];
+  guint * dimension = data[1];    
+  FttComponent c;
+
+  for (c = 0; c < *dimension; c++)
+    GFS_VARIABLE (cell, g[c]->i) = 0.;
+}
+
+static void reset_gradients (GfsDomain * domain, guint dimension, GfsVariable ** g)
+{
+  gpointer data[2];
+  data[0] = g;
+  data[1] = &dimension;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) reset_cell_gradients, data);
+}
+
+static void scale_cell_gradients (FttCell * cell, gpointer * data)
+{
+  GfsVariable ** g = data[0];
+  guint * dimension = data[1];
+  FttComponent c;
+
+  /* fixme: mapping??? */
+  if (GFS_IS_MIXED (cell)) {
+    GfsSolidVector * s = GFS_STATE (cell)->solid;
+
+    for (c = 0; c < *dimension; c++)
+      if (s->s[2*c] + s->s[2*c + 1] > 0.)
+	GFS_VARIABLE (cell, g[c]->i) /= s->s[2*c] + s->s[2*c + 1];
+      else
+	g_assert (GFS_VARIABLE (cell, g[c]->i) == 0.);
+  }
+  else {
+    FttCellNeighbors n;
+    
+    ftt_cell_neighbors (cell, &n);
+    for (c = 0; c < *dimension; c++) {
+      FttCell * c1 = n.c[2*c], * c2 = n.c[2*c + 1];
+      
+      if (c1 && c2 && !GFS_CELL_IS_GRADIENT_BOUNDARY (c1) && !GFS_CELL_IS_GRADIENT_BOUNDARY (c2))
+	GFS_VARIABLE (cell, g[c]->i) /= 2.;
+    }
+  }
+}
+
+/**
+ * gfs_scale_gradients:
+ * @domain: a #GfsDomain.
+ * @dimension: the number of dimensions.
+ * @g: the components of the gradient.
+ *
+ * Scales the gradient accumulated in @g (typically using
+ * gfs_correct_normal_velocities()).
+ */
+void gfs_scale_gradients (GfsDomain * domain, guint dimension, GfsVariable ** g)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (g != NULL);
+
+  gpointer data[2];
+  data[0] = g;
+  data[1] = &dimension;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) scale_cell_gradients, data);
+  FttComponent c;
+  for (c = 0; c < dimension; c++)
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, g[c]);
+}
+
+typedef struct {
+  GfsVariable * p, ** gv;
+  gdouble dt;
+} CorrectPar;
+
+static void correct_normal_velocity (FttCellFace * face,
+				     CorrectPar * par)
+{
+  GfsGradient g;
+  gdouble dp, f;
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  gfs_face_weighted_gradient (face, &g, par->p->i, -1);
+  dp = (g.b - g.a*GFS_VALUE (face->cell, par->p))/ftt_cell_size (face->cell);
+  if (!FTT_FACE_DIRECT (face))
+    dp = - dp;
+  f = gfs_domain_face_fraction (par->p->domain, face);
+  if (f > 0.)
+    dp /= f;
+
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) -= dp*par->dt;
+  if (par->gv)
+    GFS_VALUE (face->cell, par->gv[face->d/2]) += dp*GFS_FACE_FRACTION_LEFT (face);
+
+  if (ftt_face_type (face) == FTT_FINE_COARSE)
+    dp *= GFS_FACE_FRACTION_LEFT (face)/(GFS_FACE_FRACTION_RIGHT (face)*FTT_CELLS/2);
+  GFS_FACE_NORMAL_VELOCITY_RIGHT (face) -= dp*par->dt;
+  if (par->gv)
+    GFS_VALUE (face->neighbor, par->gv[face->d/2]) += dp*GFS_FACE_FRACTION_RIGHT (face);
+}
+
+/**
+ * gfs_correct_normal_velocities:
+ * @domain: a #GfsDomain.
+ * @dimension: the number of dimensions (2 or 3).
+ * @p: the pressure field.
+ * @g: where to store the pressure gradient or %NULL.
+ * @dt: the timestep.
+ *
+ * Corrects the normal velocity field of @domain using @p and and @dt.
+ *
+ * Assumes that the Poisson weighting coefficients have already been
+ * computed using gfs_poisson_coefficients().
+ *
+ * Also fills the @g variables (if not %NULL) with the centered
+ * gradient of @p.
+ */
+void gfs_correct_normal_velocities (GfsDomain * domain,
+				    guint dimension,
+				    GfsVariable * p,
+				    GfsVariable ** g,
+				    gdouble dt)
+{
+  CorrectPar par;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+
+  par.p = p;
+  par.gv = g;
+  par.dt = dt;
+  gfs_domain_face_traverse (domain, dimension == 2 ? FTT_XY : FTT_XYZ,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) correct_normal_velocity, &par);
+}
+
+static void scale_divergence (FttCell * cell, gpointer * data)
+{
+  GfsVariable * div = data[0];
+  gdouble * dt = data[1];
+
+  GFS_VARIABLE (cell, div->i) /= *dt;
+}
+
+typedef struct {
+  GfsSourceGeneric * s;
+  GfsVariable * v, ** g;
+  gdouble dt;
+} FaceSource;
+
+static void add_face_source (FttCellFace * face,
+			     FaceSource * f)
+{
+  gdouble dp;
+  FttComponent c;
+
+  if (GFS_FACE_FRACTION_RIGHT (face) == 0.)
+    return;
+
+  c = face->d/2;
+  dp = (* f->s->face_value) (f->s, face, f->v);
+  GFS_FACE_NORMAL_VELOCITY_LEFT (face) += dp*f->dt;
+  if (f->g)
+    GFS_VARIABLE (face->cell, f->g[c]->i) -= dp*GFS_FACE_FRACTION_LEFT (face);
+
+  if (ftt_face_type (face) == FTT_FINE_COARSE)
+    dp *= GFS_FACE_FRACTION_LEFT (face)/(GFS_FACE_FRACTION_RIGHT (face)*FTT_CELLS/2);
+  GFS_FACE_NORMAL_VELOCITY_RIGHT (face) += dp*f->dt;
+  if (f->g)
+    GFS_VARIABLE (face->neighbor, f->g[c]->i) -= dp*GFS_FACE_FRACTION_RIGHT (face);
+}
+
+static void velocity_face_sources (GfsDomain * domain,
+				   GfsVariable ** u,
+				   gdouble dt,
+				   GfsFunction * alpha,
+				   GfsVariable ** g)
+{
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    if (u[c]->sources) {
+      GSList * i = GTS_SLIST_CONTAINER (u[c]->sources)->items;
+      
+      while (i) {
+	GfsSourceGeneric * s = i->data;
+	if (s->face_value) {
+	  FaceSource f;
+	  f.s = s;
+	  f.v = u[c];
+	  f.g = g;
+	  f.dt = dt;
+	  gfs_domain_face_traverse (domain, c,
+				    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				    (FttFaceTraverseFunc) add_face_source, &f);
+	}	  
+	i = i->next;
+      }
+    }
+  if (u[0]->sources) {
+    GSList * i = GTS_SLIST_CONTAINER (u[0]->sources)->items;
+    
+    while (i) {
+      if (GFS_IS_SOURCE_TENSION (i->data)) {
+	GfsSourceTension * s = i->data;
+	gfs_source_tension_coefficients (s, domain, alpha);
+	gfs_correct_normal_velocities (domain, FTT_DIMENSION,
+				       GFS_SOURCE_TENSION_GENERIC (s)->c,
+				       g, dt);
+      }
+      i = i->next;
+    }
+  }
+}
+
+/**
+ * gfs_update_gradients:
+ * @domain: a #GfsDomain.
+ * @p: the pressure.
+ * @alpha: the Poisson equation gradient weight.
+ * @g: where to store the pressure gradient.
+ *
+ * Updates the gradients in @g using @p and @alpha.
+ */
+void gfs_update_gradients (GfsDomain * domain, 
+			   GfsVariable * p,  
+			   GfsFunction * alpha, 
+			   GfsVariable ** g)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (g != NULL);
+
+  /* Add face sources */
+  reset_gradients (domain, FTT_DIMENSION, g);
+  velocity_face_sources (domain, gfs_domain_velocity (domain), 0., alpha, g);
+  /* Initialize face coefficients */
+  gfs_poisson_coefficients (domain, alpha);
+  /* Add pressure gradient */
+  gfs_correct_normal_velocities (domain, FTT_DIMENSION, p, g, 0.);
+  gfs_scale_gradients (domain, FTT_DIMENSION, g);
+}
+
+static void mac_projection (GfsDomain * domain,
+			    GfsMultilevelParams * par,
+			    GfsAdvectionParams * apar,
+			    GfsVariable * p,
+			    GfsFunction * alpha,
+			    GfsVariable * res,
+			    GfsVariable ** g,
+			    void (* divergence_hook) (GfsDomain * domain, 
+						      GfsAdvectionParams * apar, 
+						      GfsVariable * div)
+			    )
+{
+  /* Add face sources */
+  reset_gradients (domain, FTT_DIMENSION, g);
+  velocity_face_sources (domain, gfs_domain_velocity (domain), apar->dt, alpha, g);
+
+  GfsVariable * dia = gfs_temporary_variable (domain);
+  GfsVariable * div = gfs_temporary_variable (domain);
+  GfsVariable * res1 = res ? res : gfs_temporary_variable (domain);
+
+  /* Initialize face coefficients */
+  gfs_poisson_coefficients (domain, alpha);
+
+  /* Initialize diagonal coefficient */
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			    (FttCellTraverseFunc) gfs_cell_reset, dia);
+
+  /* compute MAC divergence */
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) gfs_normal_divergence, div);
+
+  /* Divergence hook */
+  if (divergence_hook)
+    (* divergence_hook) (domain, apar, div);
+
+  /* Scale divergence */
+  gpointer data[2];
+  data[0] = div;
+  data[1] = &apar->dt;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+  			    (FttCellTraverseFunc) scale_divergence, data);
+
+#if 0
+  {
+    FILE * fp = fopen ("/tmp/mac", "wt");
+    GfsNorm norm;
+
+    gfs_write_mac_velocity (domain, 0.9, FTT_TRAVERSE_LEAFS, -1, NULL, fp);
+    fclose (fp);
+    norm = gfs_domain_norm_variable (domain, div, FTT_TRAVERSE_LEAFS, -1);
+    fprintf (stderr, "mac div before: %g %g %g\n",
+	     norm.first, norm.second, norm.infty);
+  }
+#endif
+  
+  /* compute residual */
+  par->depth = gfs_domain_depth (domain);
+  gfs_residual (domain, par->dimension, FTT_TRAVERSE_LEAFS, -1, p, div, dia, res1);
+  /* solve for pressure */
+  par->residual_before = par->residual = 
+    gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, apar->dt, res1);
+  gdouble res_max_before = par->residual.infty;
+  guint minlevel = par->minlevel;
+  par->niter = 0;
+  while (par->niter < par->nitermin ||
+	 (par->residual.infty > par->tolerance && par->niter < par->nitermax)) {
+#if 0
+    if (domain->pid <= 0)
+      fprintf (stderr, "%d bias: %g first: %g second: %g infty: %g\n",
+	       par->niter, 
+	       par->residual.bias, 
+	       par->residual.first, 
+	       par->residual.second, 
+	       par->residual.infty);
+#endif
+    gfs_poisson_cycle (domain, par, p, div, dia, res1);
+    par->residual = gfs_domain_norm_residual (domain, FTT_TRAVERSE_LEAFS, -1, apar->dt, res1);
+    if (par->residual.infty == res_max_before) /* convergence has stopped!! */
+      break;
+    if (par->residual.infty > res_max_before/1.1 && par->minlevel < par->depth)
+      par->minlevel++;
+    res_max_before = par->residual.infty;
+    par->niter++;
+  }
+  par->minlevel = minlevel;
+
+  gts_object_destroy (GTS_OBJECT (dia));
+  gts_object_destroy (GTS_OBJECT (div));
+  if (!res)
+    gts_object_destroy (GTS_OBJECT (res1));
+
+  gfs_correct_normal_velocities (domain, FTT_DIMENSION, p, g, apar->dt);
+  gfs_scale_gradients (domain, FTT_DIMENSION, g);
+}
+
+/**
+ * gfs_mac_projection:
+ * @domain: a #GfsDomain.
+ * @par: the projection control parameters.
+ * @apar: the advection parameters.
+ * @p: the pressure.
+ * @alpha: the Poisson equation gradient weight.
+ * @g: where to store the pressure gradient.
+ * @divergence_hook: a hook function or %NULL.
+ *
+ * Corrects the face-centered velocity field (MAC field) on the leaf
+ * level of @domain using an exact (MAC) projection. The resulting
+ * face-centered velocity field is (almost) exactly divergence
+ * free. The (potential) pressure field is also obtained as a
+ * by-product as well as its gradient at the center of the leaf cells
+ * of the domain. The gradient is stored in newly-allocated @g[]
+ * variables and is obtained by simple averaging from the face values
+ * to the center. The newly-allocated @g[] variables should be freed
+ * when not needed anymore.
+ *
+ * The @residual field of the @par projection parameters is set to the
+ * norm of the residual after the projection. The @niter field of the
+ * @par projection parameters is set to the number of iterations
+ * performed to solve the Poisson equation. The other projection
+ * parameters are not modified.
+ */
+void gfs_mac_projection (GfsDomain * domain,
+			 GfsMultilevelParams * par,
+			 GfsAdvectionParams * apar,
+			 GfsVariable * p,
+			 GfsFunction * alpha,
+			 GfsVariable ** g,
+			 void (* divergence_hook) (GfsDomain * domain, 
+						   GfsAdvectionParams * apar, 
+						   GfsVariable * div)
+			 )
+{
+  gdouble dt;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (apar != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (g != NULL);
+
+  gfs_domain_timer_start (domain, "mac_projection");
+
+  dt = apar->dt;
+  apar->dt /= 2.;
+
+  mac_projection (domain, par, apar, p, alpha, NULL, g, divergence_hook);
+
+#if 0
+  {
+    FILE * fp = fopen ("/tmp/macafter", "wt");
+
+    gfs_write_mac_velocity (domain, 0.9, FTT_TRAVERSE_LEAFS, -1, NULL, fp);
+    fclose (fp);
+  }
+#endif
+  
+  apar->dt = dt;
+
+  gfs_domain_timer_stop (domain, "mac_projection");
+
+  if (par->residual.infty > par->tolerance)
+    g_warning ("MAC projection: max residual %g > %g", par->residual.infty, par->tolerance);
+}
+
+static void correct (FttCell * cell, gpointer * data)
+{
+  FttComponent c;
+  GfsVariable ** v = data[0];
+  GfsVariable ** g = data[1];
+  gdouble * dt = data[2];
+  guint * dimension = data[3];
+
+  for (c = 0; c < *dimension; c++)
+    GFS_VARIABLE (cell, v[c]->i) -= GFS_VARIABLE (cell, g[c]->i)*(*dt);
+}
+
+/**
+ * gfs_correct_centered_velocities:
+ * @domain: a #GfsDomain.
+ * @dimension: the number of dimensions (2 or 3).
+ * @g: the pressure gradient.
+ * @dt: the timestep.
+ *
+ * Corrects the velocity field of @domain using the pressure gradient
+ * stored in g[].
+ *
+ * The @g[] variables are freed by this function.
+ */
+void gfs_correct_centered_velocities (GfsDomain * domain,
+				      guint dimension,
+				      GfsVariable ** g,
+				      gdouble dt)
+{
+  GfsVariable ** v;
+  FttComponent c;
+  gpointer data[4];
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (g != NULL);
+
+  data[0] = v = gfs_domain_velocity (domain);
+  data[1] = g;
+  data[2] = &dt;
+  data[3] = &dimension;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) correct, data);
+  for (c = 0; c < dimension; c++)
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, v[c]);
+}
+
+/**
+ * gfs_approximate_projection:
+ * @domain: a #GfsDomain.
+ * @par: the projection control parameters.
+ * @apar: the advection parameters.
+ * @p: the pressure.
+ * @alpha: the Poisson equation gradient weight.
+ * @res: the residual or %NULL.
+ * @g: where to store the pressure gradient.
+ * @divergence_hook: a hook function or %NULL.
+ *
+ * Corrects the centered velocity field on the leaf level of @domain
+ * using an approximate projection. The resulting centered velocity
+ * field is approximately divergence free. The (potential) pressure
+ * field is also obtained as a by-product.
+ *
+ * The @residual field of the @par projection parameters is set to the
+ * norm of the residual (on the MAC grid) after the projection. The
+ * @niter field of the @par projection parameters is set to the number
+ * of iterations performed to solve the Poisson equation. The other
+ * projection parameters are not modified.
+ *
+ * The Poisson equation for the pressure is first solved on a MAC grid
+ * where the MAC velocities are obtained from the centered velocities
+ * by simple averaging. The resulting pressure gradients (defined on
+ * the faces) are then averaged down on the center of the cells to
+ * correct the centered velocity.  
+ */
+void gfs_approximate_projection (GfsDomain * domain,
+				 GfsMultilevelParams * par,
+				 GfsAdvectionParams * apar,
+				 GfsVariable * p,
+				 GfsFunction * alpha,
+				 GfsVariable * res,
+				 GfsVariable ** g,
+				 void (* divergence_hook) (GfsDomain * domain, 
+							   GfsAdvectionParams * apar, 
+							   GfsVariable * div)
+				 )
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (apar != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (g != NULL);
+
+  gfs_domain_timer_start (domain, "approximate_projection");
+  
+  /* compute MAC velocities from centered velocities */
+  gfs_domain_face_traverse (domain, FTT_XYZ,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+  gfs_domain_face_traverse (domain, FTT_XYZ,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_interpolated_normal_velocity, 
+			    gfs_domain_velocity (domain));
+  
+  mac_projection (domain, par, apar, p, alpha, res, g, divergence_hook);
+
+  gfs_correct_centered_velocities (domain, FTT_DIMENSION, g, apar->dt);
+
+  gfs_domain_timer_stop (domain, "approximate_projection");
+
+  if (par->residual.infty > par->tolerance)
+    g_warning ("approx projection: max residual %g > %g", par->residual.infty, par->tolerance);
+}
+
+/**
+ * gfs_predicted_face_velocities:
+ * @domain: a #GfsDomain.
+ * @d: the number of dimensions (2 or 3).
+ * @par: the advection parameters.
+ *
+ * Fills the face (MAC) normal velocities of each leaf cell of @domain
+ * with the predicted values at time t + dt/2 using a godunov type
+ * advection scheme.  
+ */
+void gfs_predicted_face_velocities (GfsDomain * domain,
+				    guint d,
+				    GfsAdvectionParams * par)
+{
+  FttComponent c;
+  FttCellTraverseFunc face_values;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+
+  gfs_domain_timer_start (domain, "predicted_face_velocities");
+
+  gfs_domain_face_traverse (domain, d == 2 ? FTT_XY : FTT_XYZ,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+  par->u = gfs_domain_velocity (domain);
+  par->use_centered_velocity = TRUE;
+  if (par->scheme == GFS_NONE) {
+    face_values = (FttCellTraverseFunc) gfs_cell_non_advected_face_values;
+    par->upwinding = GFS_NO_UPWINDING;
+  }
+  else {
+    face_values = (FttCellTraverseFunc) gfs_cell_advected_face_values;
+    par->upwinding = GFS_CENTERED_UPWINDING;
+  }
+  for (c = 0; c < d; c++) {
+    par->v = par->u[c];
+    gfs_domain_cell_traverse (domain, 
+    			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+    			      face_values, par);
+    gfs_domain_face_bc (domain, c, par->v);
+    gfs_domain_face_traverse (domain, c,
+    			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) gfs_face_advected_normal_velocity, par);
+  }
+
+  gfs_domain_timer_stop (domain, "predicted_face_velocities");
+}
+
+/**
+ * gfs_diffusion:
+ * @domain: a #GfsDomain.
+ * @par: the multilevel parameters.
+ * @v: a #GfsVariable.
+ * @rhs: the right-hand side.
+ * @rhoc: the mass.
+ * @axi: the axisymmetric term.
+ *
+ * Solves a diffusion equation for variable @v using a Crank-Nicholson
+ * scheme with multilevel relaxations.
+ *
+ * Diffusion coefficients must have been set using
+ * gfs_diffusion_coefficients() and a right-hand side defined using
+ * gfs_diffusion_rhs().
+ */
+void gfs_diffusion (GfsDomain * domain,
+		    GfsMultilevelParams * par,
+		    GfsVariable * v,
+		    GfsVariable * rhs, 
+		    GfsVariable * rhoc,
+		    GfsVariable * axi)
+{
+  guint minlevel, maxlevel;
+  GfsVariable * res;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (rhs != NULL);
+  g_return_if_fail (rhoc != NULL);
+
+  res = gfs_temporary_variable (domain);
+
+  minlevel = domain->rootlevel;
+  if (par->minlevel > minlevel)
+    minlevel = par->minlevel;
+  maxlevel = gfs_domain_depth (domain);
+  gfs_diffusion_residual (domain, v, rhs, rhoc, axi, res);
+  par->residual_before = par->residual = 
+    gfs_domain_norm_variable (domain, res, NULL, FTT_TRAVERSE_LEAFS, -1);
+  gdouble res_max_before = par->residual.infty;
+  par->niter = 0;
+  while (par->niter < par->nitermin ||
+	 (par->residual.infty > par->tolerance && par->niter < par->nitermax)) {
+    gfs_diffusion_cycle (domain, minlevel, maxlevel, par->nrelax, v, rhs, rhoc, axi, res);
+    par->residual = gfs_domain_norm_variable (domain, res, NULL, FTT_TRAVERSE_LEAFS, -1);
+    if (par->residual.infty == res_max_before) /* convergence has stopped!! */
+      break;
+    if (par->residual.infty > res_max_before/1.1 && minlevel < maxlevel)
+      minlevel++;
+    res_max_before = par->residual.infty;
+#if 0
+    fprintf (stderr, "%d bias: %g first: %g second: %g infty: %g minlevel: %d\n",
+	     par->niter, 
+	     par->residual.bias, 
+	     par->residual.first, 
+	     par->residual.second, 
+	     par->residual.infty,
+	     minlevel);
+#endif
+    par->niter++;
+  }
+
+  gts_object_destroy (GTS_OBJECT (res));
+  g_assert (par->residual.infty <= par->tolerance);
+}
+
+static GfsSourceDiffusion * source_diffusion (GfsVariable * v)
+{
+  if (v->sources) {
+    GSList * i = GTS_SLIST_CONTAINER (v->sources)->items;
+    
+    while (i) {
+      GtsObject * o = i->data;
+      
+      if (GFS_IS_SOURCE_DIFFUSION (o) && 
+	  !GFS_IS_SOURCE_DIFFUSION_EXPLICIT (o) &&
+	  !GFS_IS_SOURCE_VISCOSITY_EXPLICIT (o))
+        return GFS_SOURCE_DIFFUSION (o);
+      i = i->next;
+    }
+  }
+  return NULL;
+}
+
+static void add_pressure_gradient (FttCell * cell, GfsAdvectionParams * par)
+{
+  GFS_VALUE (cell, par->fv) -= GFS_VALUE (cell, par->g[par->v->component])*par->dt;
+}
+
+static void variable_sources (GfsDomain * domain,
+			      GfsAdvectionParams * par,
+			      GfsVariable * sv,
+			      GfsVariable ** gmac,
+			      GfsVariable ** g)
+{
+  if (par->scheme == GFS_GODUNOV) {
+    GfsVariable * v = par->v;
+
+    par->u = gfs_domain_velocity (domain);
+    par->g = gmac;
+    par->fv = gfs_temporary_variable (domain);
+    par->upwinding = GFS_FACE_UPWINDING;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, par->fv);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_advected_face_values, par);
+    gfs_domain_face_bc (domain, FTT_XYZ, par->v);
+    gfs_domain_face_traverse (domain, FTT_XYZ,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) par->flux, par);
+    par->v = sv;
+    gfs_domain_traverse_merged (domain, par->update, par);
+    par->v = v;
+    par->u = par->g = NULL;
+    gts_object_destroy (GTS_OBJECT (par->fv));
+    par->fv = NULL;
+  }
+  if (g) {
+    par->fv = sv;
+    par->g = g;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) add_pressure_gradient, par);
+    par->g = NULL;
+    par->fv = NULL;
+  }
+  /* fixme: time should be set to t + dt/2 here for evaluation of
+     source terms in the call below */
+  par->fv = gfs_domain_variable_fluxes (domain, par->v, par->dt);
+  if (par->fv) {
+    GfsVariable * v = par->v;
+    par->v = sv;
+    /* fixme: for axi and moving should this be par->update? */
+    gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, par);
+    par->v = v;
+    gts_object_destroy (GTS_OBJECT (par->fv));
+    par->fv = NULL;
+  }
+  gfs_domain_variable_centered_sources (domain, par->v, sv, par->dt);
+}
+
+static void variable_diffusion (GfsDomain * domain,
+				GfsSourceDiffusion * d,
+				GfsAdvectionParams * par,
+				GfsVariable * rhs,
+				GfsFunction * alpha)
+{
+  GfsVariable * rhoc, * axi;
+
+  rhoc = gfs_temporary_variable (domain);
+  axi = GFS_IS_AXI (domain) && par->v->component == FTT_Y ? gfs_temporary_variable (domain) : NULL;
+
+  gfs_diffusion_coefficients (domain, d, par->dt, rhoc, axi, alpha, d->D->par.beta);
+  gfs_domain_surface_bc (domain, par->v);
+  gfs_diffusion_rhs (domain, par->v, rhs, rhoc, axi, d->D->par.beta);
+  /* fixme: time shoud be set to t + dt here in case boundary values are
+     time-dependent in the call below */
+  gfs_domain_surface_bc (domain, par->v);
+  gfs_diffusion (domain, &d->D->par, par->v, rhs, rhoc, axi);
+
+  if (axi)
+    gts_object_destroy (GTS_OBJECT (axi));
+  gts_object_destroy (GTS_OBJECT (rhoc));
+}
+
+static void copy_v_rhs (FttCell * cell, GfsAdvectionParams * apar)
+{
+  GFS_VALUE (cell, apar->fv) = GFS_VALUE (cell, apar->v);
+}
+
+/**
+ * gfs_centered_velocity_advection_diffusion:
+ * @domain: a #GfsDomain.
+ * @dimension: the number of dimensions (2 or 3).
+ * @par: the advection parameters.
+ * @gmac: the MAC pressure gradient.
+ * @g: the pressure gradient.
+ * @alpha: the inverse of density or %NULL.
+ *
+ * Advects the (centered) velocity field using the current
+ * face-centered (MAC) velocity field and @par->flux to compute the
+ * velocity flux through the faces of each cell.
+ *
+ * For each component of the velocity, before calling the @par->flux
+ * function the face values are first defined (at time t + dt/2) and
+ * can then be used within the @par->flux function.
+ *
+ * "Small" cut cells are treated using a cell-merging approach to
+ * avoid any restrictive CFL stability condition.  
+ *
+ * The @g[] variables are freed by this function.
+ */
+void gfs_centered_velocity_advection_diffusion (GfsDomain * domain,
+						guint dimension,
+						GfsAdvectionParams * par,
+						GfsVariable ** gmac,
+						GfsVariable ** g,
+						GfsFunction * alpha)
+{
+  FttComponent c;
+  GfsVariable ** v;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (gmac != NULL);
+
+  gfs_domain_timer_start (domain, "centered_velocity_advection_diffusion");
+
+  par->use_centered_velocity = FALSE;
+  v = gfs_domain_velocity (domain);
+  for (c = 0; c < dimension; c++) {
+    GfsSourceDiffusion * d = source_diffusion (v[c]);
+
+    par->v = v[c];
+    if (d) {
+      GfsVariable * rhs;
+
+      par->fv = rhs = gfs_temporary_variable (domain);
+      gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) copy_v_rhs, par);
+      variable_sources (domain, par, rhs, gmac, g);
+      variable_diffusion (domain, d, par, rhs, alpha);
+      gts_object_destroy (GTS_OBJECT (rhs));
+    }
+    else {
+      variable_sources (domain, par, par->v, gmac, g);
+      gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, par->v);
+    }
+  }
+  gfs_domain_timer_stop (domain, "centered_velocity_advection_diffusion");
+}
+
+/**
+ * gfs_tracer_advection_diffusion:
+ * @domain: a #GfsDomain.
+ * @par: the advection parameters.
+ *
+ * Advects the @v field of @par using the current face-centered (MAC)
+ * velocity field.
+ */
+void gfs_tracer_advection_diffusion (GfsDomain * domain,
+				     GfsAdvectionParams * par)
+{
+  GfsSourceDiffusion * d;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+
+  gfs_domain_timer_start (domain, "tracer_advection_diffusion");
+
+  if ((d = source_diffusion (par->v))) {
+    GfsVariable * rhs;
+
+    par->fv = rhs = gfs_temporary_variable (domain);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) copy_v_rhs, par);
+    variable_sources (domain, par, rhs, NULL, NULL);
+    variable_diffusion (domain, d, par, rhs, NULL);
+    gts_object_destroy (GTS_OBJECT (rhs));
+  }
+  else {
+    variable_sources (domain, par, par->v, NULL, NULL);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, par->v);
+  }
+
+  gfs_domain_timer_stop (domain, "tracer_advection_diffusion");
+}
+
+/* GfsSurfaceGenericBc: Object */
+
+static void gfs_surface_generic_bc_destroy (GtsObject * o)
+{
+  if (GFS_SURFACE_GENERIC_BC (o)->v)
+    GFS_SURFACE_GENERIC_BC (o)->v->surface_bc = NULL;
+
+  (* GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ())->parent_class->destroy) (o);
+}
+
+static void gfs_surface_generic_bc_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  GfsSurfaceGenericBc * bc = GFS_SURFACE_GENERIC_BC (*o);
+  GtsObjectClass * klass;
+
+  if (GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ())->parent_class->read) 
+      (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a class name");
+    return;
+  }
+  if (!(klass = gfs_object_class_from_name (fp->token->str))) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_surface_generic_bc_class ())) {
+    gts_file_error (fp, "class `%s' is not a GfsSurfaceGenericClass", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a variable name");
+    return;
+  }
+  bc->v = gfs_variable_from_name (domain->variables, fp->token->str);
+  if (!bc->v) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  if (bc->v->surface_bc) {
+    gts_file_error (fp, "variable `%s' already has a surface boundary condition", 
+		    fp->token->str);
+    return;
+  }
+  bc->v->surface_bc = bc;
+  gts_file_next_token (fp);
+}
+
+static void gfs_surface_generic_bc_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ())->parent_class->write) (o, fp);
+  fprintf (fp, "%s %s", o->klass->info.name, GFS_SURFACE_GENERIC_BC (o)->v->name);
+}
+
+static void gfs_surface_generic_bc_class_init (GfsSurfaceGenericBcClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_surface_generic_bc_destroy;
+  GTS_OBJECT_CLASS (klass)->read = gfs_surface_generic_bc_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_surface_generic_bc_write;
+}
+
+GfsSurfaceGenericBcClass * gfs_surface_generic_bc_class (void)
+{
+  static GfsSurfaceGenericBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_surface_generic_bc_info = {
+      "GfsSurfaceGenericBc",
+      sizeof (GfsSurfaceGenericBc),
+      sizeof (GfsSurfaceGenericBcClass),
+      (GtsObjectClassInitFunc) gfs_surface_generic_bc_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_surface_generic_bc_info);
+  }
+
+  return klass;
+}
+
+/* GfsSurfaceBc: Object */
+
+static void gfs_surface_bc_destroy (GtsObject * object)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_SURFACE_BC (object)->type));
+  gts_object_destroy (GTS_OBJECT (GFS_SURFACE_BC (object)->val));
+
+  (* GTS_OBJECT_CLASS (gfs_surface_bc_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_surface_bc_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsSurfaceBc * bc = GFS_SURFACE_BC (*o);
+
+  if (GTS_OBJECT_CLASS (gfs_surface_bc_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_surface_bc_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  if (!strcmp (fp->token->str, "Neumann")) {
+    gfs_function_set_constant_value (bc->type, 0.);
+    gts_file_next_token (fp);
+  }
+  else if (!strcmp (fp->token->str, "Dirichlet")) {
+    gfs_function_set_constant_value (bc->type, 1.);
+    gts_file_next_token (fp);
+  }
+  else {
+    gfs_function_read (bc->type, gfs_object_simulation (bc), fp);
+    if (fp->type == GTS_ERROR)
+      return;
+  }
+  gfs_function_read (bc->val, gfs_object_simulation (bc), fp);
+}
+
+static void gfs_surface_bc_write (GtsObject * o, FILE * fp)
+{
+  GfsSurfaceBc * bc = GFS_SURFACE_BC (o);
+  gdouble val;
+
+  if (GTS_OBJECT_CLASS (gfs_surface_bc_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_surface_bc_class ())->parent_class->write) (o, fp);
+  if ((val = gfs_function_get_constant_value (bc->type)) < G_MAXDOUBLE)
+    fprintf (fp, " %s", val ? "Dirichlet" : "Neumann");
+  else
+    gfs_function_write (bc->type, fp);
+  gfs_function_write (bc->val, fp);
+}
+
+static void gfs_surface_bc_bc (FttCell * cell, GfsSurfaceGenericBc * b)
+{
+  GfsSurfaceBc * bc = GFS_SURFACE_BC (b);
+
+  if (gfs_function_value (bc->type, cell) > 0.) {
+    cell->flags |= GFS_FLAG_DIRICHLET;
+    gfs_function_set_units (bc->val, GFS_SURFACE_GENERIC_BC (bc)->v->units);
+    GFS_STATE (cell)->solid->fv = gfs_function_value (bc->val, cell);
+  }
+  else {
+    cell->flags &= ~GFS_FLAG_DIRICHLET;
+    gfs_function_set_units (bc->val, GFS_SURFACE_GENERIC_BC (bc)->v->units - 1.);
+    GFS_STATE (cell)->solid->fv = gfs_function_value (bc->val, cell);
+  }
+}
+
+static void gfs_surface_bc_class_init (GfsSurfaceGenericBcClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_surface_bc_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_surface_bc_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_surface_bc_destroy;
+  klass->bc = gfs_surface_bc_bc;
+}
+
+static void gfs_surface_bc_init (GfsSurfaceBc * object)
+{
+  object->type = gfs_function_new (gfs_function_class (), 0.);
+  object->val  = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsSurfaceGenericBcClass * gfs_surface_bc_class (void)
+{
+  static GfsSurfaceGenericBcClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_surface_bc_info = {
+      "GfsSurfaceBc",
+      sizeof (GfsSurfaceBc),
+      sizeof (GfsSurfaceGenericBcClass),
+      (GtsObjectClassInitFunc) gfs_surface_bc_class_init,
+      (GtsObjectInitFunc) gfs_surface_bc_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_surface_generic_bc_class ()),
+				  &gfs_surface_bc_info);
+  }
+
+  return klass;
+}
diff --git a/src/timestep.h b/src/timestep.h
new file mode 100644
index 0000000..cc1bec6
--- /dev/null
+++ b/src/timestep.h
@@ -0,0 +1,142 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __TIMESTEP_H__
+#define __TIMESTEP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "advection.h"
+#include "poisson.h"
+#include "variable.h"
+
+void          gfs_correct_normal_velocities   (GfsDomain * domain,
+					       guint dimension,
+					       GfsVariable * p,
+					       GfsVariable ** g,
+					       gdouble dt);
+void          gfs_scale_gradients             (GfsDomain * domain, 
+					       guint dimension, 
+					       GfsVariable ** g);
+void          gfs_update_gradients            (GfsDomain * domain, 
+					       GfsVariable * p,  
+					       GfsFunction * alpha, 
+					       GfsVariable ** g);
+void          gfs_mac_projection              (GfsDomain * domain,
+					       GfsMultilevelParams * par,
+					       GfsAdvectionParams * apar,
+					       GfsVariable * p,
+					       GfsFunction * alpha,
+					       GfsVariable ** g,
+					       void (* divergence_hook) (GfsDomain * domain, 
+									 GfsAdvectionParams * apar, 
+									 GfsVariable * div)
+					       );
+void          gfs_correct_centered_velocities (GfsDomain * domain,
+					       guint dimension,
+					       GfsVariable ** g,
+					       gdouble dt);
+void          gfs_approximate_projection      (GfsDomain * domain,
+					       GfsMultilevelParams * par,
+					       GfsAdvectionParams * apar,
+					       GfsVariable * p,
+					       GfsFunction * alpha,
+					       GfsVariable * res,
+					       GfsVariable ** g,
+					       void (* divergence_hook) (GfsDomain * domain, 
+									 GfsAdvectionParams * apar, 
+									 GfsVariable * div)
+					       );
+void          gfs_predicted_face_velocities   (GfsDomain * domain,
+					       guint d,
+					       GfsAdvectionParams * par);
+
+void          gfs_diffusion                   (GfsDomain * domain,
+					       GfsMultilevelParams * par,
+					       GfsVariable * v,
+					       GfsVariable * rhs, 
+					       GfsVariable * rhoc,
+					       GfsVariable * axi);
+void          gfs_centered_velocity_advection_diffusion (GfsDomain * domain,
+							 guint dimension,
+							 GfsAdvectionParams * apar,
+							 GfsVariable ** gmac,
+							 GfsVariable ** g,
+							 GfsFunction * alpha);
+void          gfs_tracer_advection_diffusion  (GfsDomain * domain,
+					       GfsAdvectionParams * par);
+
+/* GfsSurfaceGenericBc: Header */
+
+struct _GfsSurfaceGenericBc {
+  /*< private >*/
+  GtsObject parent;
+
+  /*< public >*/
+  GfsVariable * v;  
+};
+
+typedef struct _GfsSurfaceGenericBcClass    GfsSurfaceGenericBcClass;
+
+struct _GfsSurfaceGenericBcClass {
+  /*< private >*/
+  GtsObjectClass parent_class;
+
+  /*< public >*/
+  void (* bc) (FttCell *, GfsSurfaceGenericBc *);
+};
+
+#define GFS_SURFACE_GENERIC_BC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSurfaceGenericBc,\
+					         gfs_surface_generic_bc_class ())
+#define GFS_SURFACE_GENERIC_BC_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsSurfaceGenericBcClass,\
+						 gfs_surface_generic_bc_class())
+#define GFS_IS_SURFACE_GENERIC_BC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_surface_generic_bc_class ()))
+
+GfsSurfaceGenericBcClass * gfs_surface_generic_bc_class  (void);
+
+/* GfsSurfaceBc: Header */
+
+typedef struct _GfsSurfaceBc         GfsSurfaceBc;
+
+struct _GfsSurfaceBc {
+  /*< private >*/
+  GfsSurfaceGenericBc parent;
+
+  /*< public >*/
+  GfsFunction * type, * val;
+};
+
+#define GFS_SURFACE_BC(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsSurfaceBc,\
+					         gfs_surface_bc_class ())
+#define GFS_IS_SURFACE_BC(obj)         (gts_object_is_from_class (obj,\
+						 gfs_surface_bc_class ()))
+
+GfsSurfaceGenericBcClass * gfs_surface_bc_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIMESTEP_H__ */
diff --git a/src/unstructured.c b/src/unstructured.c
new file mode 100644
index 0000000..eb21db8
--- /dev/null
+++ b/src/unstructured.c
@@ -0,0 +1,403 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric
+ * Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "unstructured.h"
+#include "variable.h"
+#include "config.h"
+#include "version.h"
+
+#define NV (4*(FTT_DIMENSION - 1))
+
+static void reset_pointers (FttCell * cell, GfsVariable ** v)
+{
+  guint i;
+  for (i = 0; i < NV; i++)
+    GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, v[i])) = NULL;
+}
+
+typedef struct {
+  FttCell * cell;
+  guint i, index;
+} Vertex;
+
+/* Using VTK convention */
+static FttDirection d[NV][FTT_DIMENSION] = {
+#if FTT_2D
+  {FTT_LEFT,FTT_BOTTOM}, {FTT_RIGHT,FTT_BOTTOM}, {FTT_LEFT,FTT_TOP}, {FTT_RIGHT,FTT_TOP},
+#else /* 3D */
+  {FTT_LEFT,FTT_BOTTOM,FTT_BACK}, {FTT_RIGHT,FTT_BOTTOM,FTT_BACK}, 
+  {FTT_LEFT,FTT_TOP,FTT_BACK}, {FTT_RIGHT,FTT_TOP,FTT_BACK},
+  {FTT_LEFT,FTT_BOTTOM,FTT_FRONT}, {FTT_RIGHT,FTT_BOTTOM,FTT_FRONT}, 
+  {FTT_LEFT,FTT_TOP,FTT_FRONT}, {FTT_RIGHT,FTT_TOP,FTT_FRONT}
+#endif /* 3D */
+};
+
+static void vertex_pos (Vertex * v, FttVector * p, GfsSimulation * sim)
+{
+  ftt_corner_pos (v->cell, d[v->i], p);
+  gfs_simulation_map_inverse (sim, p);
+}
+
+static float vertex_value (Vertex * vertex, GfsVariable * v, gint max_depth)
+{
+  return gfs_dimensional_value (v, gfs_cell_corner_value (vertex->cell, d[vertex->i], 
+							  v, max_depth));
+}
+
+typedef struct {
+  GfsVariable ** v;
+  GfsDomain * domain;
+  GSList * vertices;
+  gint max_depth;
+  guint size, index;
+} AllocParams;
+
+static void allocate_vertices (FttCell * cell, AllocParams * par)
+{
+  static gint dx[NV][FTT_DIMENSION] = {
+#if FTT_2D
+    {-1,-1}, {1,-1}, {-1,1}, {1,1},
+#else /* 3D */
+    {-1,-1,-1}, {1,-1,-1}, {-1,1,-1}, {1,1,-1},
+    {-1,-1,1},  {1,-1,1},  {-1,1,1},  {1,1,1}
+#endif /* 3D */
+  };
+
+  gdouble h = ftt_cell_size (cell)/128.;
+  guint i;
+  for (i = 0; i < NV; i++)
+    if (GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i])) == NULL) {
+      Vertex * vertex = g_malloc (par->size);
+      vertex->i = i;
+      vertex->cell = cell;
+      vertex->index = par->index++;
+      GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i])) = vertex;
+      par->vertices = g_slist_prepend (par->vertices, vertex);
+      
+      FttVector p;
+      ftt_corner_pos (cell, d[i], &p);
+      FttCell * neighbor[NV];
+      guint j;
+      for (j = 0; j < NV; j++)
+	if (i != j) {
+	  FttVector q;
+	  FttComponent c;
+	  for (c = 0; c < FTT_DIMENSION; c++)
+	    (&q.x)[c] = (&p.x)[c] - dx[j][c]*h;
+	  FttCell * n = gfs_domain_locate (par->domain, q, par->max_depth, NULL);
+	  if (n) {
+	    guint k;
+	    for (k = 0; k < j && n; k++)
+	      if (n == neighbor[k]) {
+		/* T-junction */
+#if DEBUG
+		fprintf (stderr, "tj: %g %g %g %g %g %g\n", p.x, p.y, p.z, q.x, q.y, q.z);
+#endif
+		neighbor[k] = n = NULL;
+	      }
+	  }
+	  neighbor[j] = n;
+	}
+	else
+	  neighbor[j] = NULL;
+      for (j = 0; j < NV; j++)
+	if (neighbor[j]) {
+	  g_assert (GFS_DOUBLE_TO_POINTER (GFS_VALUE (neighbor[j], par->v[j])) == NULL);
+	  GFS_DOUBLE_TO_POINTER (GFS_VALUE (neighbor[j], par->v[j])) = vertex;
+	}
+    }
+}
+
+static GSList * allocate_domain_vertices (GfsDomain * domain, 
+					  gint max_depth, 
+					  GfsVariable * v[NV],
+					  guint size)
+{
+  g_return_val_if_fail (size >= sizeof (Vertex), NULL);
+
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) reset_pointers, v);
+  AllocParams par;
+  par.v = v;
+  par.domain = domain;
+  par.max_depth = max_depth;
+  par.size = size;  
+  par.vertices = NULL;
+  par.index = 0;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) allocate_vertices, &par);
+  return g_slist_reverse (par.vertices);
+}
+
+#if DEBUG
+static void print_pos (Vertex * v)
+{
+  FttVector p;
+  ftt_corner_pos (v->cell, d[v->i], &p);
+  fprintf (stderr, "v: %g %g %g\n", p.x, p.y, p.z);
+}
+#endif /* DEBUG */
+
+#if DEBUG
+static void draw_vertices (FttCell * cell, GfsVariable ** v)
+{
+  guint i;
+  FttVector c;
+  ftt_cell_pos (cell, &c);
+  for (i = 0; i < NV; i++) {
+    Vertex * vertex = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, v[i]));
+    FttVector p;
+    ftt_corner_pos (vertex->cell, d[vertex->i], &p);
+    fprintf (stderr, "vp: %g %g\nvp: %g %g\nvp: \n", c.x, c.y, p.x, p.y);
+  }    
+}
+#endif /* DEBUG */
+
+typedef struct {
+  FILE * fp;
+  GfsVariable ** v;
+} WriteParams;
+
+static void write_element (FttCell * cell, WriteParams * par)
+{
+  fprintf (par->fp, "%d", NV);
+  guint i;
+  for (i = 0; i < NV; i++) {
+    Vertex * v = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[i]));
+    fprintf (par->fp, " %d", v->index);
+  }
+  fputc ('\n', par->fp);
+}
+
+static void cell_count (FttCell * cell, guint * count)
+{
+  (*count)++; 
+}
+
+static guint local_domain_size (GfsDomain * domain, gint max_depth)
+{
+  guint n = 0;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) cell_count, &n);
+  return n;
+}
+
+/**
+ * gfs_domain_write_vtk:
+ * @domain: a #GfsDomain.
+ * @max_depth: the maximum depth to consider.
+ * @variables: a list of #GfsVariable to output.
+ * @precision: the formatting string for converting float to ASCII.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a VTK-formatted representation of @domain and of the
+ * corresponding variables in the given list.
+ */
+void gfs_domain_write_vtk (GfsDomain * domain, gint max_depth, GSList * variables, 
+			   const gchar * precision, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (precision != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GfsVariable * v[NV];
+  guint i;
+  for (i = 0; i < NV; i++)
+    v[i] = gfs_temporary_variable (domain);
+
+  GSList * vertices = allocate_domain_vertices (domain, max_depth, v, sizeof (Vertex));
+
+  /* header */
+  fprintf (fp, 
+	   "# vtk DataFile Version 2.0\n"
+	   "Gerris simulation version %s (%s)\n"
+	   "ASCII\n"
+	   "DATASET UNSTRUCTURED_GRID\n"
+	   "\n", 
+	   GFS_VERSION,
+	   GFS_BUILD_VERSION);
+  
+  /* vertices */
+  guint nv = g_slist_length (vertices);
+  fprintf (fp, "POINTS %d float\n", nv);
+  gchar * format = g_strdup_printf ("%s %s %s\n", precision, precision, precision);
+  GSList * j = vertices;
+  while (j) {
+    FttVector p;
+    vertex_pos (j->data, &p, GFS_SIMULATION (domain));
+    fprintf (fp, format, p.x, p.y, p.z);
+    j = j->next;
+  }
+  g_free (format);
+  fputc ('\n', fp);
+
+  /* elements */
+  guint n_cells = local_domain_size (domain, max_depth);
+  fprintf (fp, "CELLS %d %d\n", n_cells, n_cells*(NV + 1));
+  WriteParams par;
+  par.v = v;
+  par.fp = fp;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) write_element, &par);
+  fprintf (fp, "\nCELL_TYPES %d\n",n_cells);
+  for (i = 0; i < n_cells; i++) {
+#if FTT_2D
+    fputs ("8\n", fp);
+#else
+    fputs ("11\n", fp);
+#endif
+  }
+  fputc ('\n', fp);
+
+#if DEBUG
+  fprintf (stderr, "vertices: %d\n", g_slist_length (vertices));
+  g_slist_foreach (vertices, (GFunc) print_pos, NULL);
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) draw_vertices, v);
+#endif /* DEBUG */
+  
+  /* write scalar fields */
+  if (variables) {
+    gchar * format = g_strdup_printf ("%s\n", precision);
+    fprintf (fp, "POINT_DATA %d\n", nv);
+    GSList * i = variables;
+    while (i) {
+      GfsVariable * v = i->data;
+      fprintf (fp, "SCALARS %s float\nLOOKUP_TABLE default\n", v->name);
+      GSList * j = vertices;
+      while (j) {
+	Vertex * vertex = j->data;
+	fprintf (fp, format, vertex_value (vertex, v, max_depth));
+	j = j->next;
+      }
+      fputc ('\n', fp);
+      i = i->next;
+    }
+    g_free (format);
+  }
+
+  /* cleanup */
+  g_slist_foreach (vertices, (GFunc) g_free, NULL);
+  g_slist_free (vertices);
+  for (i = 0; i < NV; i++)
+    gts_object_destroy (GTS_OBJECT (v[i]));
+}
+
+static void write_tecplot_element (FttCell * cell, WriteParams * par)
+{
+  static guint tecplot_index[NV] = {
+#if FTT_2D
+    0, 1, 3, 2
+#else /* 3D */
+    0, 1, 3, 2,
+    4, 5, 7, 6
+#endif /* 3D */
+  };
+  guint i;
+  for (i = 0; i < NV; i++) {
+    Vertex * v = GFS_DOUBLE_TO_POINTER (GFS_VALUE (cell, par->v[tecplot_index[i]]));
+    fprintf (par->fp, "%d ", v->index + 1);
+  }
+  fputc ('\n', par->fp);
+}
+
+/**
+ * gfs_domain_write_tecplot:
+ * @domain: a #GfsDomain.
+ * @max_depth: the maximum depth to consider.
+ * @variables: a list of #GfsVariable to output.
+ * @precision: the formatting string for converting float to ASCII.
+ * @fp: a file pointer.
+ *
+ * Writes in @fp a Tecplot-formatted representation of @domain and of the
+ * corresponding variables in the given list.
+ */
+void gfs_domain_write_tecplot (GfsDomain * domain, gint max_depth, GSList * variables, 
+			       const gchar * precision, FILE * fp)
+{
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (precision != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GfsVariable * v[NV];
+  guint i;
+  for (i = 0; i < NV; i++)
+    v[i] = gfs_temporary_variable (domain);
+
+  GSList * vertices = allocate_domain_vertices (domain, max_depth, v, sizeof (Vertex));
+
+  /* header */
+  fprintf (fp,
+	   " TITLE = \"Gerris simulation version %s (%s)\"\n",
+	   GFS_VERSION,
+	   GFS_BUILD_VERSION);
+
+  fputs (FTT_DIMENSION == 2 ? " VARIABLES = 'X', 'Y'" : " VARIABLES = 'X', 'Y', 'Z'", fp);
+  GSList * j = variables;
+  while (j) {
+    GfsVariable * v = j->data;
+    fprintf (fp, ", '%s'", v->name);
+    j = j->next;
+  }
+  fputc ('\n', fp);
+
+  guint nv = g_slist_length (vertices);
+  guint n_cells = local_domain_size (domain, max_depth);
+  fprintf (fp, " ZONE N=%i, E=%i, F=FEPOINT, ", nv, n_cells);
+  fputs (FTT_DIMENSION == 2 ? "ET=QUADRILATERAL\n" : "ET=BRICK\n", fp);
+  
+  /* vertices and scalar data */
+  gchar * xyzformat = 
+#if FTT_2D
+    g_strdup_printf ("%s %s", precision, precision);
+#else
+    g_strdup_printf ("%s %s %s", precision, precision, precision);
+#endif
+  gchar * format = g_strdup_printf (" %s", precision);
+  j = vertices;
+  while (j) {
+    Vertex * vertex = j->data;
+    FttVector p;
+    vertex_pos (vertex, &p, GFS_SIMULATION (domain));
+    fprintf (fp, xyzformat, p.x, p.y, p.z);
+    GSList * k = variables;
+    while (k) {
+      fprintf (fp, format, vertex_value (vertex, k->data, max_depth));
+      k = k->next;
+    }
+    fputc ('\n', fp);
+    j = j->next;
+  }
+  g_free (format);
+  g_free (xyzformat);
+
+  /* elements */
+  WriteParams par;
+  par.v = v;
+  par.fp = fp;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, max_depth,
+			    (FttCellTraverseFunc) write_tecplot_element, &par);
+
+  /* cleanup */
+  g_slist_foreach (vertices, (GFunc) g_free, NULL);
+  g_slist_free (vertices);
+  for (i = 0; i < NV; i++)
+    gts_object_destroy (GTS_OBJECT (v[i]));
+}
diff --git a/src/unstructured.h b/src/unstructured.h
new file mode 100644
index 0000000..7af76d9
--- /dev/null
+++ b/src/unstructured.h
@@ -0,0 +1,45 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric
+ * Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __UNSTRUCTURED_H__
+#define __UNSTRUCTURED_H__
+
+#include "domain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void gfs_domain_write_vtk     (GfsDomain * domain, 
+			       gint max_depth, 
+			       GSList * variables, 
+			       const gchar * precision,
+			       FILE * fp);
+void gfs_domain_write_tecplot (GfsDomain * domain, 
+			       gint max_depth, 
+			       GSList * variables, 
+			       const gchar * precision,
+			       FILE * fp);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __UNSTRUCTURED_H__ */
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..ba9a698
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,1688 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/times.h>
+#include "config.h"
+#include "solid.h"
+#include "simulation.h"
+#include "cartesian.h"
+
+/**
+ * @c: a character.
+ * @s: a string.
+ *
+ * Returns: %TRUE if @c belongs to @s, %FALSE otherwise.
+ */
+gboolean gfs_char_in_string (char c, const char * s)
+{
+  if (s == NULL)
+    return FALSE;
+  while (*s != '\0')
+    if (*(s++) == c)
+      return TRUE;
+  return FALSE;
+}
+
+/**
+ * gfs_file_statement:
+ * @fp: a #GtsFile.
+ *
+ * Reads the next brackets-delimited ({...}) statemement in @fp,
+ * including all comments.
+ *
+ * Returns: a newly allocated string containing the text of the next
+ * statement in @fp, or %NULL if an error occured in which case
+ * @fp->error is set.
+ */
+gchar * gfs_file_statement (GtsFile * fp)
+{
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  if (fp->type != '{') {
+    gts_file_error (fp, "expecting an opening brace");
+    return NULL;
+  }
+  GString * s = g_string_new ("");
+  gchar empty[] = "", * comments = fp->comments;
+  fp->comments = empty;
+  guint scope = fp->scope_max;
+  gint c = gts_file_getc (fp);
+  while (c != EOF && fp->scope > scope) {
+    g_string_append_c (s, c);
+    c = gts_file_getc (fp);
+  }
+  fp->comments = comments;
+  if (fp->scope != scope) {
+    gts_file_error (fp, "parse error");
+    g_string_free (s, TRUE);
+    return NULL;
+  }
+  gchar * ret = s->str;
+  g_string_free (s, FALSE);
+  return ret;
+}
+
+typedef gdouble (* GfsFunctionFunc) (const FttCell * cell,
+				     const FttCellFace * face,
+				     GfsSimulation * sim);
+typedef gdouble (* GfsFunctionDerivedFunc) (const FttCell * cell,
+					    const FttCellFace * face,
+					    GfsSimulation * sim,
+					    gpointer data);
+
+static GfsDerivedVariable * lookup_derived_variable (const gchar * name,
+						     GSList * i)
+{
+  while (i) {
+    GfsDerivedVariable * v = i->data;
+    if (!strcmp (v->name, name))
+      return v;
+    i = i->next;
+  }
+  return NULL;
+}
+
+/* GfsGlobal: Object */
+
+struct _GfsGlobal {
+  /*< private >*/
+  GtsObject parent;
+
+  /*< public >*/
+  gchar * s;
+  guint line;
+};
+
+static void global_destroy (GtsObject * object)
+{
+  g_free (GFS_GLOBAL (object)->s);
+  (* gfs_global_class ()->parent_class->destroy) (object);
+}
+
+static void global_write (GtsObject * object, FILE * fp)
+{
+  fprintf (fp, "%s {", object->klass->info.name);
+  fputs (GFS_GLOBAL (object)->s, fp);
+  fputs ("}\n", fp);
+}
+
+static void global_read (GtsObject ** object, GtsFile * fp)
+{
+  GfsGlobal * global = GFS_GLOBAL (*object);
+  GtsObjectClass * klass;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (GfsGlobalClass)");
+    return;
+  }
+  klass = gfs_object_class_from_name (fp->token->str);
+  if (klass == NULL) {
+    gts_file_error (fp, "unknown class `%s'", fp->token->str);
+    return;
+  }
+  if (!gts_object_class_is_from_class (klass, gfs_global_class ())) {
+    gts_file_error (fp, "`%s' is not a GfsGlobal", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+  global->line = fp->line;
+  g_free (global->s);
+  if ((global->s = gfs_file_statement (fp)))
+    gts_file_next_token (fp);
+}
+
+static void gfs_global_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = global_destroy;
+  klass->read =    global_read;
+  klass->write =   global_write;
+}
+
+GtsObjectClass * gfs_global_class (void)
+{
+  static GtsObjectClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_global_info = {
+      "GfsGlobal",
+      sizeof (GfsGlobal),
+      sizeof (GtsObjectClass),
+      (GtsObjectClassInitFunc) gfs_global_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_global_info);
+  }
+
+  return klass;
+}
+
+/* GfsFunction: Object */
+
+struct _GfsFunction {
+  GtsObject parent;
+  GString * expr;
+  gboolean isexpr;
+  GModule * module;
+  GfsFunctionFunc f;
+  gchar * sname;
+  GtsSurface * s;
+  GfsCartesianGrid * g;
+  guint index[4];
+  GfsVariable * v;
+  GfsDerivedVariable * dv;
+  gdouble val;
+  gboolean spatial, constant, nomap;
+  GtsFile fpd;
+  gdouble units;
+};
+
+static GtsSurface * read_surface (gchar * name, GtsFile * fp)
+{
+  FILE * fptr = fopen (name, "r");
+  GtsSurface * s;
+  GtsFile * fp1;
+
+  if (fptr == NULL) {
+    gts_file_error (fp, "cannot open file `%s'", name);
+    return NULL;
+  }
+  fp1 = gts_file_new (fptr);
+  s = gts_surface_new (gts_surface_class (), gts_face_class (), 
+		       gts_edge_class (), gts_vertex_class ());
+  if (gts_surface_read (s, fp1)) {
+    gts_file_error (fp, "%s:%d:%d: %s", name, fp1->line, fp1->pos, fp1->error);
+    gts_object_destroy (GTS_OBJECT (s));
+    s = NULL;
+  }
+  gts_file_destroy (fp1);
+  fclose (fptr);
+  return s;
+}
+
+static GfsCartesianGrid * read_cartesian_grid (gchar * name, GtsFile * fp)
+{
+  FILE * fptr = fopen (name, "r");
+  GtsFile * fp1;
+  GfsCartesianGrid * grid;
+  GtsObjectClass * klass;
+
+  if (fptr == NULL) {
+    gts_file_error (fp, "cannot open file `%s'", name);
+    return NULL;
+  }
+
+  fp1 = gts_file_new (fptr);
+
+  klass = gfs_cartesian_grid_class ();
+
+  grid = gfs_cartesian_grid_new (klass);
+  GtsObject * o = GTS_OBJECT (grid);
+  (* klass->read) (&o, fp1);
+
+  if (fp1->type == GTS_ERROR) {
+    gts_file_error (fp, "%s:%d:%d: %s", name, fp1->line, fp1->pos, fp1->error);
+    gts_object_destroy (GTS_OBJECT(grid));
+    grid = NULL;
+  }
+  gts_file_destroy (fp1);
+  fclose (fptr);
+  return grid;
+}
+
+static gboolean fit_index_dimension (GfsCartesianGrid * grid, guint * val, GtsFile * fp)
+{
+  guint i, j;
+  gchar list[] = {'x','y','z','t'};
+
+  if (grid->N > 4) {
+    gts_file_error (fp, "Cartesian grids can only use four dimensions or less");
+    return FALSE;
+  }
+
+  for (i = 0; i < grid->N; i++) {
+    for (j = 0; j < 4 && *grid->name[i] != list[j]; j++);
+    if (j == 4) {
+      gts_file_error (fp, "unknown Cartesian grid index `%s'", grid->name[i]);
+      return FALSE;
+    }
+    val[i] = j;
+  }
+  return TRUE;
+}
+
+static gboolean cgd_is_spatial (GfsFunction * f)
+{
+  guint i;
+  for (i = 0; i < f->g->N; i++)
+    if (f->index[i] < 3)
+      return TRUE;
+  return FALSE;
+}
+
+static gdouble interpolated_cgd (GfsFunction * f, FttVector * p)
+{
+  gdouble vector[4];
+  gdouble val;
+  guint i;
+
+  gfs_simulation_map_inverse (gfs_object_simulation (f), p);
+  for (i = 0; i < f->g->N; i++)
+    switch (f->index[i]) {
+    case 0: vector[i] = p->x; break;
+    case 1: vector[i] = p->y; break;
+    case 2: vector[i] = p->z; break;
+    case 3: vector[i] = gfs_object_simulation (f)->time.t; break;
+    default: g_assert_not_reached ();
+    }
+
+  if (!gfs_cartesian_grid_interpolate (f->g, vector, &val))
+    return 0.;
+  return val;
+}
+
+static gboolean load_module (GfsFunction * f, GtsFile * fp, gchar * mname)
+{
+  gchar * path;
+  
+  path = g_module_build_path (GFS_MODULES_DIR, mname);
+  f->module = g_module_open (path, 0);
+  g_free (path);
+  if (f->module == NULL)
+    f->module = g_module_open (mname, 0);
+  if (f->module == NULL) {
+    gts_file_error (fp, "cannot load module: %s", g_module_error ());
+    return FALSE;
+  }
+  if (!g_module_symbol (f->module, "f", (gpointer) &f->f)) {
+    gts_file_error (fp, "module `%s' does not export function `f'", mname);
+    g_module_close (f->module);
+    return FALSE;
+  }
+  if (f->constant) {
+    f->val = (* f->f) (NULL, NULL, NULL);
+    f->f = NULL;
+    g_module_close (f->module);
+    f->module = NULL;
+    if (f->expr) g_string_free (f->expr, TRUE);
+    f->expr = NULL;
+  }
+  return TRUE;
+}
+
+/**
+ * gfs_function_expression:
+ * @fp: a #GtsFile.
+ * @is_expression: a pointer to a boolean or %NULL.
+ *
+ * Reads the expression (in which case @is_expression is set to %TRUE)
+ * or function from @fp.
+ *
+ * Returns: a newly allocated GString containing the result or %NULL
+ * in case of error.
+ */
+GString * gfs_function_expression (GtsFile * fp, gboolean * is_expression)
+{
+  GString * expr = NULL;
+
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  if (is_expression)
+    *is_expression = TRUE;
+  if (fp->type == '{') {
+    gchar * s = gfs_file_statement (fp);
+    if (fp->type == GTS_ERROR)
+      return NULL;
+    expr = g_string_new ("{");
+    g_string_append (expr, s);
+    g_free (s);
+    g_string_append_c (expr, '}');
+    if (is_expression)
+      *is_expression = FALSE;
+    return expr;
+  }
+  else {
+    static gchar spaces[] = " \t\f\r";
+    static gchar operators[] = "+-*/%<>=&^|?:!";
+    gboolean is_constant = (fp->type == GTS_INT || fp->type == GTS_FLOAT);
+    gint c, scope = 0;
+    gchar * s;
+    gchar empty[] = "", * comments = fp->comments;
+
+    fp->comments = empty;
+    expr = g_string_new (fp->token->str);
+    s = expr->str;
+    while (*s != '\0') {
+      if (*s == '(') scope++;
+      else if (*s == ')') scope--;
+      s++;
+    }
+    if (fp->next_token != '\0')
+      c = fp->next_token;
+    else {
+      if (fp->type != '(')
+	c = ' ';
+      else
+	c = gts_file_getc (fp);
+    }
+    if (strlen (expr->str) == 1 && gfs_char_in_string (expr->str[0], operators))
+      while (c != EOF && gfs_char_in_string (c, spaces)) {
+	g_string_append_c (expr, c);
+	c = gts_file_getc (fp);
+      }
+    while (c != EOF) {
+      if (gfs_char_in_string (c, "{}\n")) {
+	fp->next_token = c;
+	break;
+      }
+      else if (scope > 0) {
+	while (c != EOF && scope > 0) {
+	  if (c == '(') scope++;
+	  else if (c == ')') scope--;
+	  g_string_append_c (expr, c);
+	  c = gts_file_getc (fp);
+	}
+      }
+      else if (gfs_char_in_string (c, spaces)) {
+	while (c != EOF && gfs_char_in_string (c, spaces)) {
+	  g_string_append_c (expr, c);
+	  c = gts_file_getc (fp);
+	}
+	if (c == '(') {
+	  if (is_constant) {
+	    fp->next_token = c;
+	    break;
+	  }
+	  scope++;
+	  g_string_append_c (expr, c);
+	  c = gts_file_getc (fp);
+	}
+	else {
+	  if (!gfs_char_in_string (c, operators)) {
+	    fp->next_token = c;
+	    break;
+	  }
+	  is_constant = FALSE;
+	  g_string_append_c (expr, c);
+	  c = gts_file_getc (fp);
+	  while (c != EOF && gfs_char_in_string (c, spaces)) {
+	    g_string_append_c (expr, c);
+	    c = gts_file_getc (fp);
+	  }
+	}
+      }
+      else if (gfs_char_in_string (c, operators)) {
+	is_constant = FALSE;
+	g_string_append_c (expr, c);
+	c = gts_file_getc (fp);
+	while (c != EOF && gfs_char_in_string (c, spaces)) {
+	  g_string_append_c (expr, c);
+	  c = gts_file_getc (fp);
+	}
+      }
+      else {
+	is_constant = FALSE;
+	if (c == '(') scope++;
+	else if (c == ')') scope--;
+	if (scope < 0) {
+	  fp->next_token = c;
+	  break;
+	}
+	g_string_append_c (expr, c);
+	c = gts_file_getc (fp);
+      }
+    }
+    g_strchomp (expr->str);
+    fp->comments = comments;
+    return expr;
+  }
+}
+
+static gint compile (GtsFile * fp, GfsFunction * f, const gchar * finname)
+{
+  gchar foutname[] = "/tmp/gfsXXXXXX";
+  gchar ferrname[] = "/tmp/gfsXXXXXX";
+  gchar ftmpname[] = "/tmp/gfsXXXXXX";
+  gint foutd, ferrd, ftmpd;
+  gchar * cc;
+  gint status;
+  gchar cccommand[] = "gcc `pkg-config "
+#if FTT_2D
+    "gerris2D"
+#elif FTT_2D3
+    "gerris2D3"
+#else /* 3D */
+    "gerris3D"
+#endif
+    " --cflags --libs` -O -Wall -Wno-unused -Werror "
+    MODULES_FLAGS;
+  
+  foutd = mkstemp (foutname);
+  ferrd = mkstemp (ferrname);
+  ftmpd = mkstemp (ftmpname);
+  if (foutd < 0 || ferrd < 0 || ftmpd < 0) {
+    gts_file_error (fp, "cannot create temporary file");
+    return SIGABRT;
+  }
+  cc = g_strjoin (" ",
+		  cccommand, ftmpname, 
+		  "-o", foutname,
+                  "`sed 's/@/#/g' <", finname,
+		  "| awk '{"
+		  "   if ($1 == \"#\" && $2 == \"link\") {"
+		  "     for (i = 3; i <= NF; i++) printf (\"%s \", $i);"
+		  "     print \"\" > \"/dev/stderr\";"
+		  "   }"
+		  "   else if ($1 == \"#link\") {"
+		  "     for (i = 2; i <= NF; i++) printf (\"%s \", $i);"
+		  "     print \"\" > \"/dev/stderr\";"
+		  "   } else print $0 > \"/dev/stderr\";"
+		  "}' 2>", ftmpname, "` 2>",
+		  ferrname, NULL);
+  status = system (cc);
+  g_free (cc);
+  close (ftmpd);
+  remove (ftmpname);
+  if (WIFSIGNALED (status) && (WTERMSIG (status) == SIGINT || WTERMSIG (status) == SIGQUIT))
+    status = SIGQUIT;
+  else if (status == -1 || WEXITSTATUS (status) != 0) {
+    GString * msg = g_string_new ("");
+    FILE * ferr = fdopen (ferrd, "r");
+    gchar * needle;
+    gint c;
+
+    while ((c = fgetc (ferr)) != EOF)
+      g_string_append_c (msg, c);
+    fclose (ferr);
+    while ((needle = strstr (msg->str, "GfsFunction:")))
+      g_string_erase (msg, needle - msg->str, strlen ("GfsFunction:"));
+    gts_file_error (fp, "error compiling expression\n%s", msg->str);
+    g_string_free (msg, TRUE);
+    status = SIGABRT;
+  }
+  else {
+    if (load_module (f, fp, foutname))
+      status = SIGCONT;
+    else
+      status = SIGABRT;
+  }
+  close (foutd);
+  remove (foutname);
+  close (ferrd);
+  remove (ferrname);
+  return status;
+}
+
+static gchar * find_identifier (const gchar * s, const gchar * i)
+{
+  gchar * f = strstr (s, i);
+  static gchar allowed[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
+
+  while (f) {
+    if (gfs_char_in_string (f[strlen(i)], allowed) ||
+	(f > s && gfs_char_in_string (f[-1], allowed)))
+      f = strstr (++f, i);
+    else
+      return f;
+  }
+  return NULL;
+}
+
+static void function_compile (GfsFunction * f, GtsFile * fp)
+{
+  if (!HAVE_PKG_CONFIG) {
+    gts_file_error (fp, "expecting a number, variable or GTS surface (val)\n"
+		    "(functions are not supported on this system)");
+    return;
+  }
+  else {
+    GfsSimulation * sim = gfs_object_simulation (f);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    gchar finname[] = "/tmp/gfsXXXXXX";
+    gint find, status;
+    FILE * fin;
+    GSList * lv = NULL, * ldv = NULL, * i;
+
+    find = mkstemp (finname);
+    if (find < 0) {
+      gts_file_error (fp, "cannot create temporary file");
+      return;
+    }
+    fin = fdopen (find, "w");
+    fputs ("#include <stdlib.h>\n"
+	   "#include <stdio.h>\n"
+	   "#include <math.h>\n"
+	   "#include <gfs.h>\n",
+	   fin);
+    if (f->spatial)
+      fputs ("#include <gerris/spatial.h>\n", fin);
+    else if (!f->constant)
+      fputs ("#include <gerris/function.h>\n", fin);
+    i = sim->globals;
+    while (i) {
+      fprintf (fin, "#line %d \"GfsGlobal\"\n", GFS_GLOBAL (i->data)->line);
+      fputs (GFS_GLOBAL (i->data)->s, fin);
+      fputc ('\n', fin);
+      i = i->next;
+    }
+    if (f->spatial)
+      fputs ("double f (double x, double y, double z, double t) {\n"
+	     "  _x = x; _y = y; _z = z;\n", 
+	     fin);
+    else if (f->constant)
+      fputs ("double f (void) {\n", fin);
+    else {
+      fputs ("typedef double (* Func) (const FttCell * cell,\n"
+	     "                         const FttCellFace * face,\n"
+	     "                         GfsSimulation * sim,\n"
+	     "                         gpointer data);\n"
+	     "double f (FttCell * cell, FttCellFace * face, GfsSimulation * sim) {\n"
+	     "  _sim = sim; _cell = cell;\n",
+	     fin);
+      i = domain->variables;
+      while (i) {
+	if (GFS_VARIABLE1 (i->data)->name && 
+	    find_identifier (f->expr->str, GFS_VARIABLE1 (i->data)->name))
+	  lv = g_slist_prepend (lv, i->data);
+	i = i->next;
+      }
+      i = domain->derived_variables;
+      while (i) {
+	GfsDerivedVariable * v = i->data;
+	if (find_identifier (f->expr->str, v->name))
+	  ldv = g_slist_prepend (ldv, v);
+	i = i->next;
+      }
+      if (lv || ldv) {
+	GSList * i = lv;
+
+	while (i) {
+	  GfsVariable * v = i->data;
+	  fprintf (fin, "  double %s;\n", v->name);
+	  i = i->next;
+	}
+	i = ldv;
+	while (i) {
+	  GfsDerivedVariable * v = i->data;
+	  fprintf (fin, "  double %s;\n", v->name);
+	  i = i->next;
+	}
+	if (lv) {
+	  fputs ("  if (cell) {\n", fin);
+	  i = lv;
+	  while (i) {
+	    GfsVariable * v = i->data;
+	    fprintf (fin, 
+		     "    %s = gfs_dimensional_value (GFS_VARIABLE1 (%p),\n"
+		     "           GFS_VALUE (cell, GFS_VARIABLE1 (%p)));\n", 
+		     v->name, v, v);
+	    i = i->next;
+	  }
+	  fputs ("  } else {\n", fin);
+	  i = lv;
+	  while (i) {
+	    GfsVariable * v = i->data;
+	    fprintf (fin, 
+		     "    %s = gfs_dimensional_value (GFS_VARIABLE1 (%p),\n"
+		     "           gfs_face_interpolated_value (face, GFS_VARIABLE1 (%p)->i));\n", 
+		     v->name, v, v);
+	    i = i->next;
+	  }
+	  fputs ("  }\n", fin);
+	  g_slist_free (lv);
+	}
+	if (ldv) {
+	  i = ldv;
+	  while (i) {
+	    GfsDerivedVariable * v = i->data;
+	    fprintf (fin, "  %s = (* (Func) %p) (cell, face, sim, ((GfsDerivedVariable *) %p)->data);\n", 
+		     v->name, v->func, v);
+	    i = i->next;
+	  }
+	  g_slist_free (ldv);
+	}
+      }
+    }
+    fprintf (fin, "#line %d \"GfsFunction\"\n", fp->line);
+
+    if (f->isexpr)
+      fprintf (fin, "return %s;\n}\n", f->expr->str);
+    else {
+      gchar * s = f->expr->str;
+      guint len = strlen (s);
+      g_assert (s[0] == '{' && s[len-1] == '}');
+      s[len-1] = '\0';
+      fprintf (fin, "%s\n}\n", &s[1]);
+      s[len-1] = '}';
+    }
+    fclose (fin);
+    close (find);
+
+    status = compile (fp, f, finname);
+    remove (finname);
+    switch (status) {
+    case SIGQUIT: exit (0);
+    case SIGABRT: return;
+    }
+  }  
+}
+
+#define DEFERRED_COMPILATION ((GfsFunctionFunc) 0x1)
+
+static void check_for_deferred_compilation (GfsFunction * f)
+{
+  if (f->f == DEFERRED_COMPILATION) {
+    function_compile (f, &f->fpd);
+    if (f->fpd.type == GTS_ERROR) {
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, 
+	     "error in deferred compilation\n%s", 
+	     f->fpd.error);
+      exit (1);
+    }
+  }
+}
+
+static void function_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsFunction * f = GFS_FUNCTION (*o);
+  GfsSimulation * sim;
+  GfsDomain * domain;
+
+  if (GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  sim = gfs_object_simulation (*o);
+  domain = GFS_DOMAIN (sim);
+  if (fp->type != GTS_INT && fp->type != GTS_FLOAT && fp->type != GTS_STRING &&
+      fp->type != '(' && fp->type != '{') {
+    gts_file_error (fp, "expecting an expression (val)");
+    return;
+  }
+
+  if (fp->type == GTS_STRING && !f->spatial && !f->constant && strlen (fp->token->str) > 3) {
+    if (!strcmp (&(fp->token->str[strlen (fp->token->str) - 4]), ".gts")) {
+      if ((f->s = read_surface (fp->token->str, fp)) == NULL)
+	return;
+      f->sname = g_strdup (fp->token->str);
+      gts_file_next_token (fp);
+      return;
+    }
+    else if (!strcmp (&(fp->token->str[strlen (fp->token->str) - 4]), ".cgd")) {
+      if ((f->g = read_cartesian_grid (fp->token->str, fp)) == NULL)
+	return;
+      if (!fit_index_dimension (f->g, f->index, fp))
+	return;
+      f->sname = g_strdup (fp->token->str);
+      gts_file_next_token (fp);
+      return;
+    }   
+  }
+
+  if ((f->expr = gfs_function_expression (fp, &f->isexpr)) == NULL)
+    return;
+
+  if (f->isexpr) {
+    if (fp->type == GTS_INT || fp->type == GTS_FLOAT) {
+      if (!strcmp (fp->token->str, f->expr->str)) {
+	f->val = atof (fp->token->str);
+	gts_file_next_token (fp);
+	return;
+      }
+    }
+    else if (fp->type == GTS_STRING && !f->spatial && !f->constant) {
+      if ((f->v = gfs_variable_from_name (domain->variables, f->expr->str)) ||
+	  (f->dv = lookup_derived_variable (f->expr->str, domain->derived_variables))) {
+	gts_file_next_token (fp);
+	return;
+      }
+    }
+  }
+
+  if (sim->deferred_compilation) {
+    f->f = DEFERRED_COMPILATION;
+    f->fpd = *fp;
+  }
+  else
+    function_compile (f, fp);
+
+  if (fp->type == GTS_ERROR)
+    return;
+  gts_file_next_token (fp);
+}
+
+static void function_write (GtsObject * o, FILE * fp)
+{
+  GfsFunction * f = GFS_FUNCTION (o);
+
+  if (GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->write) (o, fp);
+
+  if (f->expr)
+    fprintf (fp, " %s", f->expr->str);
+  else if (f->module)
+    fprintf (fp, " %s", g_module_name (f->module));
+  else if (f->v)
+    fprintf (fp, " %s", f->v->name);
+  else if (f->s || f->g)
+    fprintf (fp, " %s", f->sname);
+  else
+    fprintf (fp, " %g", f->val);
+}
+
+static void function_destroy (GtsObject * object)
+{
+  GfsFunction * f = GFS_FUNCTION (object);
+
+  if (f->module) g_module_close (f->module);
+  if (f->expr) g_string_free (f->expr, TRUE);
+  if (f->s) {
+    gts_object_destroy (GTS_OBJECT (f->s));
+    g_free (f->sname);
+  }
+  if (f->g) {
+    gts_object_destroy (GTS_OBJECT (f->g));
+    g_free (f->sname);
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_function_class ())->parent_class->destroy) 
+    (object);
+}
+
+static void gfs_function_class_init (GfsFunctionClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = function_read;
+  GTS_OBJECT_CLASS (klass)->write = function_write;
+  GTS_OBJECT_CLASS (klass)->destroy = function_destroy;
+}
+
+GfsFunctionClass * gfs_function_class (void)
+{
+  static GfsFunctionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_function_info = {
+      "GfsFunction",
+      sizeof (GfsFunction),
+      sizeof (GfsFunctionClass),
+      (GtsObjectClassInitFunc) gfs_function_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()),
+				  &gfs_function_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_function_new:
+ * @klass: a #GfsFunctionClass.
+ * @val: a value.
+ *
+ * Returns: a new #GfsFunction with constant value @val.
+ */
+GfsFunction * gfs_function_new (GfsFunctionClass * klass, 
+				gdouble val)
+{
+  GfsFunction * object;
+
+  object = GFS_FUNCTION (gts_object_new (GTS_OBJECT_CLASS (klass)));
+  object->val = val;
+
+  return object;
+}
+
+GfsFunction * gfs_function_new_from_variable (GfsFunctionClass * klass, 
+					      GfsVariable * v)
+{
+  GfsFunction * object;
+
+  g_return_val_if_fail (v != NULL, NULL);
+
+  object = GFS_FUNCTION (gts_object_new (GTS_OBJECT_CLASS (klass)));
+  object->v = v;
+
+  return object;
+}
+
+/**
+ * gfs_function_set_units:
+ * @f: a #GfsFunction.
+ * @units: the units of @f.
+ *
+ * Sets the units of @f.
+ */
+void gfs_function_set_units (GfsFunction * f, 
+			     gdouble units)
+{
+  g_return_if_fail (f != NULL);
+  f->units = units;
+}
+
+static gdouble interpolated_value (GfsFunction * f, FttVector * p)
+{
+  GtsPoint q;
+  GtsFace * t;
+
+  gfs_simulation_map_inverse (gfs_object_simulation (f), p);
+  q.x = p->x; q.y = p->y;
+  t = gts_point_locate (&q, f->s, NULL);
+  if (t == NULL)
+    return 0.;
+  gts_triangle_interpolate_height (GTS_TRIANGLE (t), &q);
+  return q.z;
+}
+
+/**
+ * gfs_function_description:
+ * @f: a #GfsFunction.
+ * @truncate: whether to truncate long descriptions.
+ *
+ * Returns: a newly allocated string describing @f.
+ */
+gchar * gfs_function_description (GfsFunction * f,
+				  gboolean truncate)
+{
+  gchar * s;
+
+  g_return_val_if_fail (f != NULL, NULL);
+
+  if (f->s)
+    s = g_strdup (f->sname);
+  else if (f->v)
+    s = g_strdup (f->v->name);
+  else if (f->expr) {
+    s = g_strdup (f->expr->str);    
+    if (truncate) {
+      gchar * c = s;
+      guint n = 0;
+      
+      while (*c != '\0' && !isspace (*c))
+	c++;
+      while (*c != '\0' && n < 3) {
+	*c = '.';
+	c++; n++;
+      }
+      *c = '\0';
+    }
+  }
+  else
+    s = g_strdup_printf ("%g", f->val);
+  return s;
+}
+
+static gdouble adimensional_value (GfsFunction * f, gdouble v)
+{
+  gdouble L;
+  if (v == G_MAXDOUBLE || f->units == 0. || 
+      (L = gfs_object_simulation (f)->physical_params.L) == 1.)
+    return v;
+  return v*pow (L, - f->units);
+}
+
+/**
+ * gfs_function_value:
+ * @f: a #GfsFunction.
+ * @cell: a #FttCell or %NULL.
+ *
+ * Returns: the value of function @f in @cell.
+ */
+gdouble gfs_function_value (GfsFunction * f, FttCell * cell)
+{
+  g_return_val_if_fail (f != NULL, 0.);
+
+  gdouble dimensional;
+  if (f->s) {
+    FttVector p;
+    gfs_cell_cm (cell, &p);
+    dimensional = interpolated_value (f, &p);
+  }
+  else if (f->g) {
+    FttVector p = {0.,0.,0.};
+    if (cgd_is_spatial (f))
+      gfs_cell_cm (cell, &p);
+    dimensional = interpolated_cgd (f, &p);
+  }
+  else if (f->v)
+    dimensional = gfs_dimensional_value (f->v, GFS_VALUE (cell, f->v));
+  else if (f->dv)
+    dimensional = (* (GfsFunctionDerivedFunc) f->dv->func) (cell, NULL,
+							    gfs_object_simulation (f),
+							    f->dv->data);
+  else if (f->f) {
+    check_for_deferred_compilation (f);
+    dimensional = (* f->f) (cell, NULL, gfs_object_simulation (f));
+  }
+  else
+    dimensional = f->val;
+  return adimensional_value (f, dimensional);
+}
+
+/**
+ * gfs_function_face_value:
+ * @f: a #GfsFunction.
+ * @fa: a #FttCellFace.
+ *
+ * Returns: the value of function @f at the center of face @fa.
+ */
+gdouble gfs_function_face_value (GfsFunction * f, FttCellFace * fa)
+{
+  g_return_val_if_fail (f != NULL, 0.);
+  g_return_val_if_fail (fa != NULL, 0.);
+
+  gdouble dimensional;
+  if (f->s) {
+    FttVector p;
+    ftt_face_pos (fa, &p);
+    dimensional = interpolated_value (f, &p);
+  }
+  else if (f->g) {
+    FttVector p = {0.,0.,0.};
+    if (cgd_is_spatial (f))
+      ftt_face_pos (fa, &p);
+    dimensional = interpolated_cgd (f, &p);
+  }
+  else if (f->v)
+    dimensional = gfs_dimensional_value (f->v, gfs_face_interpolated_value (fa, f->v->i));
+  else if (f->dv)
+    dimensional = (* (GfsFunctionDerivedFunc) f->dv->func) (NULL, fa,
+							    gfs_object_simulation (f),
+							    f->dv->data);
+  else if (f->f) {
+    check_for_deferred_compilation (f);
+    dimensional = (* f->f) (NULL, fa, gfs_object_simulation (f));
+  }
+  else
+    dimensional = f->val;
+  return adimensional_value (f, dimensional);
+}
+
+/**
+ * gfs_function_set_constant_value:
+ * @f: a #GfsFunction.
+ * @val: the value.
+ *
+ * Sets the value of the constant function @f to @val.
+ */
+void gfs_function_set_constant_value (GfsFunction * f, gdouble val)
+{
+  g_return_if_fail (f != NULL);
+  g_return_if_fail (!f->f && !f->s && !f->v && !f->dv);
+
+  f->val = val;
+}
+
+/**
+ * gfs_function_get_constant_value:
+ * @f: a #GfsFunction.
+ *
+ * Returns: the value of function @f if @f is constant, G_MAXDOUBLE
+ * otherwise.
+ */
+gdouble gfs_function_get_constant_value (GfsFunction * f)
+{
+  g_return_val_if_fail (f != NULL, G_MAXDOUBLE);
+
+  check_for_deferred_compilation (f);
+  if (f->f || f->s || f->v || f->dv)
+    return G_MAXDOUBLE;
+  else
+    return adimensional_value (f, f->val);
+}
+
+/**
+ * gfs_function_get_variable:
+ * @f: a #GfsFunction.
+ *
+ * Returns: the variable containing the value of @f if @f is a simple
+ * variable, NULL otherwise.
+ */
+GfsVariable * gfs_function_get_variable (GfsFunction * f)
+{
+  g_return_val_if_fail (f != NULL, NULL);
+
+  return f->v;
+}
+
+/**
+ * gfs_function_read:
+ * @f: a #GfsFunction.
+ * @domain: a #GfsDomain.
+ * @fp: a #GtsFile.
+ *
+ * Calls the read() method of @f.
+ */
+void gfs_function_read (GfsFunction * f, gpointer domain, GtsFile * fp)
+{
+  GtsObject * o = (GtsObject *) f;
+
+  g_return_if_fail (f != NULL);
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (fp != NULL);
+
+  GTS_OBJECT (f)->reserved = domain;
+  (* GTS_OBJECT (f)->klass->read) (&o, fp);
+}
+
+/**
+ * gfs_function_write:
+ * @f: a #GfsFunction.
+ * @fp: a file pointer.
+ *
+ * Calls the write() method of @f.
+ */
+void gfs_function_write (GfsFunction * f, FILE * fp)
+{
+  g_return_if_fail (f != NULL);
+  g_return_if_fail (fp != NULL);
+
+  (* GTS_OBJECT (f)->klass->write) (GTS_OBJECT (f), fp);
+}
+
+/* GfsFunctionSpatial: object */
+
+static void gfs_function_spatial_init (GfsFunction * f)
+{
+  f->spatial = TRUE;
+}
+
+GfsFunctionClass * gfs_function_spatial_class (void)
+{
+  static GfsFunctionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_function_info = {
+      "GfsFunctionSpatial",
+      sizeof (GfsFunction),
+      sizeof (GfsFunctionClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) gfs_function_spatial_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_function_class ()),
+				  &gfs_function_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_function_spatial_value:
+ * @f: a #GfsFunction.
+ * @p: a #FttVector.
+ *
+ * Returns: the value of function @f at location @p.
+ */
+gdouble gfs_function_spatial_value (GfsFunction * f, const FttVector * p)
+{
+  g_return_val_if_fail (f != NULL, 0.);
+  g_return_val_if_fail (GFS_IS_FUNCTION_SPATIAL (f), 0.);
+  g_return_val_if_fail (p != NULL, 0.);
+
+  gdouble dimensional;  
+  if (f->f) {
+    GfsSimulation * sim = gfs_object_simulation (f);
+    FttVector q = *p;
+    check_for_deferred_compilation (f);
+    if (!f->nomap)
+      gfs_simulation_map_inverse (sim, &q);
+    dimensional = (* (GfsFunctionSpatialFunc) f->f) (q.x, q.y, q.z, sim->time.t);
+  }
+  else
+    dimensional = f->val;
+  return adimensional_value (f, dimensional);
+}
+
+GfsFunction * gfs_function_spatial_new (GfsFunctionClass * klass, 
+					GfsFunctionSpatialFunc func)
+{
+  GfsFunction * object;
+
+  g_return_val_if_fail (func != NULL, NULL);
+
+  object = GFS_FUNCTION (gts_object_new (GTS_OBJECT_CLASS (klass)));
+  object->f = (GfsFunctionFunc) func;
+
+  return object;
+}
+
+/* GfsFunctionMap: object */
+
+static void gfs_function_map_init (GfsFunction * f)
+{
+  f->nomap = TRUE;
+}
+
+GfsFunctionClass * gfs_function_map_class (void)
+{
+  static GfsFunctionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_function_info = {
+      "GfsFunctionMap",
+      sizeof (GfsFunction),
+      sizeof (GfsFunctionClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) gfs_function_map_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_function_spatial_class ()),
+				  &gfs_function_info);
+  }
+
+  return klass;
+}
+
+/* GfsFunctionConstant: object */
+
+static void gfs_function_constant_init (GfsFunction * f)
+{
+  f->constant = TRUE;
+}
+
+GfsFunctionClass * gfs_function_constant_class (void)
+{
+  static GfsFunctionClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_function_info = {
+      "GfsFunctionConstant",
+      sizeof (GfsFunction),
+      sizeof (GfsFunctionClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) gfs_function_constant_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_function_class ()),
+				  &gfs_function_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_read_constant:
+ * @fp: a #GtsFile.
+ * @domain: a #GfsDomain.
+ *
+ * Reads a constant value from @fp.
+ *
+ * Returns: the value of the constant or G_MAXDOUBLE if an error
+ * occured.
+ */
+gdouble gfs_read_constant (GtsFile * fp, gpointer domain)
+{
+  g_return_val_if_fail (fp != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (domain != NULL, G_MAXDOUBLE);
+
+  GfsFunction * f = gfs_function_new (gfs_function_constant_class (), 0.);
+  gfs_function_read (f, domain, fp);
+  if (fp->type == GTS_ERROR)
+    return G_MAXDOUBLE;
+  gdouble val = gfs_function_get_constant_value (f);
+  gts_object_destroy (GTS_OBJECT (f));
+  if (val == G_MAXDOUBLE)
+    gts_file_error (fp, "expecting a constant");
+  return val;
+}
+
+/**
+ * gfs_object_class_from_name:
+ * @name: the name of the class.
+ *
+ * Looks for a class called @name. If none is found append the "Gfs"
+ * prefix and look again.
+ *
+ * Returns: the class or %NULL if none was found.
+ */
+GtsObjectClass * gfs_object_class_from_name (const gchar * name)
+{
+  GtsObjectClass * klass;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  if ((klass = gts_object_class_from_name (name)))
+    return klass;
+  /* for backward parameter file compatibility */
+  if (!strcmp (name, "GtsSurfaceFile"))
+    return GTS_OBJECT_CLASS (gfs_solid_class ());
+  gchar * ename = g_strconcat ("Gfs", name, NULL);
+  klass = gts_object_class_from_name (ename);
+  g_free (ename);
+  return klass;
+}
+
+static void eigsrt (gdouble d[FTT_DIMENSION], gdouble v[FTT_DIMENSION][FTT_DIMENSION])
+{
+  gint k, j, i;
+  gdouble p;
+
+  for (i = 0; i < FTT_DIMENSION - 1; i++) {
+    p = d[k = i];
+
+    for (j = i + 1; j < FTT_DIMENSION; j++)
+      if (d[j] >= p) 
+	p = d[k = j];
+    if (k != i) {
+      d[k] = d[i];
+      d[i] = p;
+      for (j = 0; j < FTT_DIMENSION; j++) {
+	p = v[j][i];
+	v[j][i] = v[j][k];
+	v[j][k] = p;
+      }
+    }
+  }
+}
+
+#define ROTATE(a,i,j,k,l) {g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);a[k][l]=h+s*(g-h*tau);}
+
+/**
+ * gfs_eigenvalues:
+ * @a: a symmetric matrix.
+ * @d: a vector.
+ * @v: another matrix.
+ *
+ * Fills @d (resp. @v) with the eigenvalues (resp. eigenvectors) of
+ * matrix @a.
+ */
+void gfs_eigenvalues (gdouble a[FTT_DIMENSION][FTT_DIMENSION],
+		      gdouble d[FTT_DIMENSION],
+		      gdouble v[FTT_DIMENSION][FTT_DIMENSION])
+{
+  gint j, iq, ip, i;
+  gdouble tresh, theta, tau, t, sm, s, h, g, c, b[FTT_DIMENSION], z[FTT_DIMENSION];
+
+  for (ip = 0; ip < FTT_DIMENSION; ip++) {
+    for (iq = 0; iq < FTT_DIMENSION; iq++)
+      v[ip][iq] = 0.0;
+    v[ip][ip] = 1.0;
+  }
+
+  for (ip = 0; ip < FTT_DIMENSION; ip++) {
+    b[ip] = d[ip] = a[ip][ip];
+    z[ip] = 0.0;
+  }
+
+  for (i = 1; i <= 50; i++) {
+    sm = 0.0;
+    for (ip = 0; ip < FTT_DIMENSION - 1; ip++) {
+      for (iq = ip + 1; iq < FTT_DIMENSION; iq++)
+	sm += fabs (a[ip][iq]);
+    }
+    if (sm == 0.0) {
+      eigsrt (d, v);
+      return;
+    }
+    if (i < 4)
+      tresh = 0.2*sm/(FTT_DIMENSION*FTT_DIMENSION);
+    else
+      tresh = 0.0;
+    for (ip = 0; ip < FTT_DIMENSION - 1; ip++) {
+      for (iq = ip + 1; iq < FTT_DIMENSION; iq++) {
+	g = 100.0*fabs (a[ip][iq]);
+	if (i > 4 && fabs(d[ip]) + g == fabs(d[ip]) && fabs(d[iq]) + g == fabs(d[iq]))
+	  a[ip][iq] = 0.0;
+	else if (fabs (a[ip][iq]) > tresh) {
+	  h = d[iq] - d[ip];
+	  if (fabs(h) + g == fabs(h))
+	    t = a[ip][iq]/h;
+	  else {
+	    theta = 0.5*h/a[ip][iq];
+	    t = 1.0/(fabs (theta) + sqrt (1.0 + theta*theta));
+	    if (theta < 0.0) t = -t;
+	  }
+	  c = 1.0/sqrt (1 + t*t);
+	  s = t*c;
+	  tau = s/(1.0 + c);
+	  h = t*a[ip][iq];
+	  z[ip] -= h;
+	  z[iq] += h;
+	  d[ip] -= h;
+	  d[iq] += h;
+	  a[ip][iq] = 0.0;
+	  for (j = 0; j <= ip - 1; j++)
+	    ROTATE (a, j, ip, j, iq);
+	  for (j = ip + 1; j <= iq - 1; j++)
+	    ROTATE (a, ip, j, j, iq);
+	  for (j = iq + 1; j < FTT_DIMENSION; j++)
+	    ROTATE(a, ip, j, iq, j);
+	  for (j = 0; j < FTT_DIMENSION; j++)
+	    ROTATE(v, j, ip, j, iq);
+	}
+      }
+    }
+    for (ip = 0; ip < FTT_DIMENSION; ip++) {
+      b[ip] += z[ip];
+      d[ip] = b[ip];
+      z[ip] = 0.0;
+    }
+  }
+  /* Too many iterations */
+  for (i = 0; i < FTT_DIMENSION; i++) {
+    for (j = 0; j < FTT_DIMENSION; j++)
+      fprintf (stderr, "%10.3g ", a[i][j]);
+    fprintf (stderr, "\n");
+  }
+  g_assert_not_reached ();
+}
+
+/**
+ * gfs_matrix_inverse:
+ * @m: a square matrix.
+ * @n: size of the matrix.
+ * @pivmin: the minimum value of the pivoting coefficient.
+ *
+ * Replaces @m with its inverse.
+ *
+ * Returns: 0. if the inversion encounters a pivot coefficient smaller
+ * than or equal to @pivmin (i.e. @m is non-invertible), the minimum
+ * absolute value of the pivoting coefficient otherwise.
+ */
+gdouble gfs_matrix_inverse (gdouble ** m, guint n, gdouble pivmin)
+{
+  gint * indxc, * indxr, * ipiv;
+  gint i, icol = 0, irow = 0, j, k, l, ll;
+  gdouble big, dum, pivinv, temp, minpiv = G_MAXDOUBLE;
+
+  g_return_val_if_fail (m != NULL, 0.);
+  g_return_val_if_fail (pivmin >= 0., 0.);
+
+  indxc = g_malloc (sizeof (gint)*n);
+  indxr = g_malloc (sizeof (gint)*n);
+  ipiv = g_malloc (sizeof (gint)*n);
+  
+#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
+
+  for (j = 0; j < n; j++)
+    ipiv[j] = -1;
+
+  for (i = 0; i < n; i++) {
+    big = 0.0;
+    for (j = 0; j < n; j++)
+      if (ipiv[j] != 0)
+	for (k = 0; k < n; k++) {
+	  if (ipiv[k] == -1) {
+	    if (fabs (m[j][k]) >= big) {
+	      big = fabs (m[j][k]);
+	      irow = j;
+	      icol = k;
+	    }
+	  }
+	}
+    ipiv[icol]++;
+    if (irow != icol)
+      for (l = 0; l < n; l++) 
+	SWAP (m[irow][l], m[icol][l]);
+    indxr[i] = irow;
+    indxc[i] = icol;
+    if (fabs (m[icol][icol]) <= pivmin) {
+      g_free (indxc);
+      g_free (indxr);
+      g_free (ipiv);
+      return 0.;
+    }
+    if (fabs (m[icol][icol]) < minpiv)
+      minpiv = fabs (m[icol][icol]);
+    pivinv = 1.0/m[icol][icol];
+    m[icol][icol] = 1.0;
+    for (l = 0; l < n; l++) m[icol][l] *= pivinv;
+    for (ll = 0; ll < n; ll++)
+      if (ll != icol) {
+	dum = m[ll][icol];
+	m[ll][icol] = 0.0;
+	for (l = 0; l < n; l++)
+	  m[ll][l] -= m[icol][l]*dum;
+      }
+  }
+  for (l = n - 1; l >= 0; l--) {
+    if (indxr[l] != indxc[l])
+      for (k = 0; k < n; k++)
+	SWAP (m[k][indxr[l]], m[k][indxc[l]]);
+  }
+  g_free (indxc);
+  g_free (indxr);
+  g_free (ipiv);
+  return minpiv;
+}
+
+/**
+ * gfs_matrix_new:
+ * @n: the size of the matrix.
+ * @p: the size of the matrix.
+ * @size: the size of the matrix elements.
+ *
+ * The matrix elements are initialised to zero.
+ *
+ * Returns: a newly allocated matrix.
+ */
+gpointer gfs_matrix_new (guint n, guint p, guint size)
+{
+  guint i;
+  gpointer * m, a;
+  
+  g_return_val_if_fail (n > 0, NULL);
+  g_return_val_if_fail (p > 0, NULL);
+  g_return_val_if_fail (size > 0, NULL);
+
+  m = g_malloc (n*sizeof (gpointer));
+  a = g_malloc0 (n*p*size);
+  for (i = 0; i < n; i++)
+    m[i] = GUINT_TO_POINTER (GPOINTER_TO_UINT (a) + i*p*size);
+  return m;
+}
+
+/**
+ * gfs_matrix_free:
+ * @m: a matrix allocated with gfs_matrix_new().
+ *
+ * Frees the memory occupied by @m.
+ */
+void gfs_matrix_free (gpointer m)
+{
+  g_return_if_fail (m != NULL);
+
+  g_free (((gpointer *) m)[0]);
+  g_free (m);
+}
+
+/**
+ * gfs_clock_new:
+ *
+ * Returns: a new #GfsClock.
+ */
+GfsClock * gfs_clock_new (void)
+{
+  GfsClock * t = g_malloc (sizeof (GfsClock));
+
+  t->start = -1;
+  t->started = FALSE;
+  return t;
+}
+
+/**
+ * gfs_clock_start:
+ * @t: a #GfsClock.
+ *
+ * Starts clock @t.
+ */
+void gfs_clock_start (GfsClock * t)
+{
+  struct tms tm;
+
+  g_return_if_fail (t != NULL);
+  g_return_if_fail (!t->started);
+
+  if (times (&tm) == (clock_t) -1)
+    g_warning ("cannot read clock");
+  t->start = tm.tms_utime;
+  t->started = TRUE;
+}
+
+/**
+ * gfs_clock_stop:
+ * @t: a #GfsClock.
+ *
+ * Stops clock @t.
+ */
+void gfs_clock_stop (GfsClock * t)
+{
+  struct tms tm;
+
+  g_return_if_fail (t != NULL);
+  g_return_if_fail (t->started);
+
+  if (times (&tm) == (clock_t) -1)
+    g_warning ("cannot read clock");
+  t->stop = tm.tms_utime;
+  t->started = FALSE;
+}
+
+/**
+ * gfs_clock_elapsed:
+ * @t: a #GfsClock.
+ *
+ * Returns: the time elapsed in seconds since @t was started.
+ */
+gdouble gfs_clock_elapsed (GfsClock * t)
+{
+  g_return_val_if_fail (t != NULL, 0.);
+  g_return_val_if_fail (t->start >= 0, 0.);
+
+  if (t->started == FALSE)
+    return (t->stop - t->start)/(gdouble) sysconf (_SC_CLK_TCK);
+  else {
+    struct tms tm;
+    if (times (&tm) == (clock_t) -1)
+      g_warning ("cannot read clock");
+    return (tm.tms_utime - t->start)/(gdouble) sysconf (_SC_CLK_TCK);
+  }
+}
+
+/**
+ * gfs_clock_destroy:
+ * @t: a #GfsClock.
+ *
+ * Destroys the clock, freeing the memory allocated for it.
+ */
+void gfs_clock_destroy (GfsClock * t)
+{
+  g_return_if_fail (t != NULL);
+
+  g_free (t);
+}
+
+/**
+ * gfs_union_open:
+ * @fp: a file pointer.
+ * @rank: the rank of the current parallel process.
+ *
+ * Opens a "parallel" file which serialises multiple parallel (write)
+ * accesses to the file pointed to by @fp.
+ *
+ * This file must be closed with gfs_union_close().
+ *
+ * Returns: a "parallel" file pointer associated with @fp.
+ */
+FILE * gfs_union_open (FILE * fp, int rank)
+{
+  g_return_val_if_fail (fp != NULL, NULL);
+
+  if (rank <= 0) /* master */
+    return fp;
+  else { /* slaves */
+#ifdef HAVE_MPI
+    MPI_Status status;
+    int pe;
+    MPI_Recv (&pe, 1, MPI_INT, 0, rank, MPI_COMM_WORLD, &status);
+    g_assert (rank == pe);
+#endif /* HAVE_MPI */
+    return tmpfile ();
+  }
+}
+
+/**
+ * gfs_union_close:
+ * @fp: a file pointer.
+ * @rank: the rank of the current parallel process.
+ * @fpp: a "parallel" file pointer returned by a call to gfs_union_open().
+ *
+ * Closes a "parallel" file previously opened using gfs_union_open().
+ */
+void gfs_union_close (FILE * fp, int rank, FILE * fpp)
+{
+  g_return_if_fail (fp != NULL);
+  g_return_if_fail (fpp != NULL);
+
+  if (rank == 0) { /* master */
+#ifdef HAVE_MPI
+    int pe, npe;
+    MPI_Comm_size (MPI_COMM_WORLD, &npe);
+    for (pe = 1; pe < npe; pe++) {
+      MPI_Send (&pe, 1, MPI_INT, pe, pe, MPI_COMM_WORLD);
+      MPI_Status status;
+      long length;
+      MPI_Recv (&length, 1, MPI_LONG, pe, pe, MPI_COMM_WORLD, &status);
+      /*      fprintf (stderr, "receiving %ld bytes from PE %d\n", length, pe); */
+      if (length > 0) {
+	char * buf = g_malloc (length);
+	MPI_Recv (buf, length, MPI_BYTE, pe, pe + 1, MPI_COMM_WORLD, &status);
+	int rcvcount;
+	MPI_Get_count (&status, MPI_BYTE, &rcvcount);
+	fwrite (buf, 1, rcvcount, fp);
+	g_free (buf);
+      }
+    }
+#endif /* HAVE_MPI */
+  }
+  else if (rank > 0) { /* slaves */
+#ifdef HAVE_MPI
+    int fd = fileno (fpp);
+    struct stat sb;
+    fflush (fpp);
+    g_assert (fstat (fd, &sb) != -1);
+    long length = sb.st_size;
+    MPI_Send (&length, 1, MPI_LONG, 0, rank, MPI_COMM_WORLD);
+    if (length > 0) {
+      char * buf = mmap (NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
+      g_assert (buf != MAP_FAILED);
+      MPI_Send (buf, length, MPI_BYTE, 0, rank + 1, MPI_COMM_WORLD);
+      munmap (buf, length);
+    }
+#endif /* HAVE_MPI */
+    fclose (fpp);
+  }
+}
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..7f070ee
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,191 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gmodule.h>
+#include "ftt.h"
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#  ifdef HAVE_MPI
+#    include <mpi.h>
+
+# define gfs_all_reduce(domain, p, type, op) {			        \
+    if ((domain)->pid >= 0) {						\
+      union { int a; float b; double c;} global;			\
+      MPI_Allreduce (&(p), &global, 1, type, op, MPI_COMM_WORLD);	\
+      memcpy (&(p), &global, sizeof (p));				\
+    }									\
+  }
+
+# define gfs_error(pid, ...) {	                                        \
+    int rank;                                                           \
+    MPI_Comm_rank (MPI_COMM_WORLD, &rank);                              \
+    if (rank == (pid))		             				\
+      fprintf (stderr, __VA_ARGS__);                                    \
+    else if ((pid) < 0) {						\
+      int size;                                                         \
+      MPI_Comm_size (MPI_COMM_WORLD, &size);                            \
+      if (size > 1) {			                                \
+        char name[MPI_MAX_PROCESSOR_NAME];                              \
+        MPI_Get_processor_name (name, &size);                           \
+        fprintf (stderr, "PE %d (%s): ", rank, name);			\
+      }                                                                 \
+      fprintf (stderr, __VA_ARGS__);                                    \
+    }                                                                   \
+  }
+
+#  else /* doesn't HAVE_MPI */
+    /* gfs_all_reduce() defaults to nothing without MPI */
+#    define gfs_all_reduce(domain, p, type, op)
+#    define gfs_error(pid, ...) fprintf(stderr, __VA_ARGS__)
+#  endif /* doesn't HAVE_MPI */
+#endif /* HAVE_CONFIG_H */
+
+#define GFS_DOUBLE_TO_POINTER(d)     (*((gpointer *) &(d)))
+
+gboolean gfs_char_in_string (char c, const char * s);
+gchar *  gfs_file_statement (GtsFile * fp);
+
+/* GfsGlobal: Header */
+
+typedef struct _GfsGlobal         GfsGlobal;
+
+#define GFS_GLOBAL(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsGlobal,\
+					         gfs_global_class ())
+#define GFS_IS_GLOBAL(obj)         (gts_object_is_from_class (obj,\
+						 gfs_global_class ()))
+
+GtsObjectClass * gfs_global_class  (void);
+
+/* GfsFunction: Header */
+
+typedef struct _GfsFunction         GfsFunction;
+
+typedef struct _GfsFunctionClass    GfsFunctionClass;
+
+struct _GfsFunctionClass {
+  GtsObjectClass parent_class;
+};
+
+#define GFS_FUNCTION(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsFunction,\
+					         gfs_function_class ())
+#define GFS_FUNCTION_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsFunctionClass,\
+						 gfs_function_class())
+#define GFS_IS_FUNCTION(obj)         (gts_object_is_from_class (obj,\
+						 gfs_function_class ()))
+
+GfsFunctionClass * gfs_function_class       (void);
+GfsFunction *      gfs_function_new         (GfsFunctionClass * klass,
+					     gdouble val);
+GfsFunction *      gfs_function_new_from_variable (GfsFunctionClass * klass, 
+						   GfsVariable * v);
+void               gfs_function_set_units   (GfsFunction * f,
+					     gdouble units);
+gchar *            gfs_function_description (GfsFunction * f,
+					     gboolean truncate);
+gdouble            gfs_function_face_value  (GfsFunction * f,
+					     FttCellFace * fa);
+gdouble            gfs_function_value       (GfsFunction * f,
+					     FttCell * cell);
+void               gfs_function_set_constant_value (GfsFunction * f, 
+						    gdouble val);
+gdouble            gfs_function_get_constant_value (GfsFunction * f);
+GfsVariable *      gfs_function_get_variable (GfsFunction * f);
+void               gfs_function_read        (GfsFunction * f, 
+					     gpointer domain,
+					     GtsFile * fp);
+void               gfs_function_write       (GfsFunction * f, 
+					     FILE * fp);
+GString *          gfs_function_expression  (GtsFile * fp, 
+					     gboolean * is_expression);
+
+/* GfsFunctionSpatial: Header */
+
+#define GFS_IS_FUNCTION_SPATIAL(obj)         (gts_object_is_from_class (obj,\
+					      gfs_function_spatial_class ()))
+
+typedef gdouble (* GfsFunctionSpatialFunc)    (double x, double y, double z, double t);
+
+GfsFunctionClass * gfs_function_spatial_class (void);
+GfsFunction *      gfs_function_spatial_new   (GfsFunctionClass * klass, 
+					       GfsFunctionSpatialFunc func);
+gdouble            gfs_function_spatial_value (GfsFunction * f, const FttVector * p);
+
+/* GfsFunctionMap: Header */
+
+#define GFS_IS_FUNCTION_MAP(obj)         (gts_object_is_from_class (obj,\
+					      gfs_function_map_class ()))
+
+GfsFunctionClass * gfs_function_map_class (void);
+
+/* GfsFunctionConstant: Header */
+
+#define GFS_IS_FUNCTION_CONSTANT(obj)         (gts_object_is_from_class (obj,\
+					       gfs_function_constant_class ()))
+
+GfsFunctionClass * gfs_function_constant_class (void);
+gdouble            gfs_read_constant           (GtsFile * fp,
+						gpointer domain);
+
+GtsObjectClass *   gfs_object_class_from_name (const gchar * name);
+
+void               gfs_eigenvalues          (gdouble a[FTT_DIMENSION][FTT_DIMENSION],
+					     gdouble d[FTT_DIMENSION],
+					     gdouble v[FTT_DIMENSION][FTT_DIMENSION]);
+gdouble            gfs_matrix_inverse       (gdouble ** m, 
+					     guint n,
+					     gdouble pivmin);
+gpointer           gfs_matrix_new           (guint n, 
+					     guint p,
+					     guint size);
+void               gfs_matrix_free          (gpointer m);
+
+typedef struct {
+  gboolean started;
+  glong start, stop;
+} GfsClock;
+
+GfsClock *         gfs_clock_new            (void);
+void               gfs_clock_start          (GfsClock * t);
+void               gfs_clock_stop           (GfsClock * t);
+gdouble            gfs_clock_elapsed        (GfsClock * t);
+void               gfs_clock_destroy        (GfsClock * t);
+
+FILE *             gfs_union_open           (FILE * fp, 
+					     int rank);
+void               gfs_union_close          (FILE * fp, 
+					     int rank, 
+					     FILE * fpp);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __UTILS_H__ */
+
diff --git a/src/variable.c b/src/variable.c
new file mode 100644
index 0000000..184df36
--- /dev/null
+++ b/src/variable.c
@@ -0,0 +1,847 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "variable.h"
+#include "vof.h"
+
+/* GfsVariable: Object */
+
+static void variable_init_domain (GfsVariable * v, GfsDomain * domain)
+{
+  v->i = gfs_domain_alloc (domain);
+  v->domain = domain;
+  GTS_OBJECT (v)->reserved = domain;
+}
+
+static void gfs_variable_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsDomain * domain;
+  GfsVariable * v, * old;
+
+  if (GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->read)
+    (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (name)");
+    return;
+  }
+  domain = (*o)->reserved;
+  if (gfs_derived_variable_from_name (domain->derived_variables, fp->token->str)) {
+    gts_file_error (fp, "`%s' is a reserved keyword", fp->token->str);
+    return;
+  }
+  v = GFS_VARIABLE1 (*o);
+  v->name = g_strdup (fp->token->str);
+  gts_file_next_token (fp);
+
+  if ((old = gfs_variable_from_name (domain->variables, v->name))) {
+    GSList * i;
+    if ((i = g_slist_find (domain->variables_io, old)))
+      i->data = v;
+    domain->variables = g_slist_remove (domain->variables, old);
+    v->units = old->units;
+    gts_object_destroy (GTS_OBJECT (old));
+  }
+  variable_init_domain (v, domain);
+  domain->variables = g_slist_append (domain->variables, v);
+}
+
+static void gfs_variable_write (GtsObject * o, FILE * fp)
+{
+  if (GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->write)
+    (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->write) (o, fp);
+  fprintf (fp, " %s", GFS_VARIABLE1 (o)->name);
+}
+
+static void gfs_variable_destroy (GtsObject * object)
+{
+  GfsVariable * v = GFS_VARIABLE1 (object);
+
+  g_free (v->name);
+  g_free (v->description);
+  if (v->sources)
+    gts_object_destroy (GTS_OBJECT (v->sources));
+  if (v->surface_bc)
+    gts_object_destroy (GTS_OBJECT (v->surface_bc));
+  if (v->default_bc)
+    gts_object_destroy (GTS_OBJECT (v->default_bc));
+  if (v->domain) {
+    gfs_domain_free (v->domain, v->i);
+    v->domain->variables = g_slist_remove (v->domain->variables, v);
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_variable_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_variable_class_init (GfsVariableClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->read = gfs_variable_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_variable_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_variable_destroy;
+}
+
+static void gfs_variable_init (GfsVariable * v)
+{
+  GFS_EVENT (v)->istep = 1;
+  v->centered = FALSE;
+  v->component = FTT_DIMENSION;
+  v->fine_coarse = (GfsVariableFineCoarseFunc) gfs_get_from_below_intensive;
+  v->coarse_fine = (GfsVariableFineCoarseFunc) gfs_cell_coarse_fine;
+}
+
+GfsVariableClass * gfs_variable_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_info = {
+      "GfsVariable",
+      sizeof (GfsVariable),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) gfs_variable_class_init,
+      (GtsObjectInitFunc) gfs_variable_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_event_class ()), &gfs_variable_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_variable_new:
+ * @klass: a #GfsVariableClass.
+ * @domain: a #GfsDomain.
+ * @name: the name of the variable or %NULL.
+ * @description: the variable description or %NULL.
+ *
+ * Returns: a newly allocated #GfsVariable or %NULL if a variable
+ * named @name already exists in @domain.
+ */
+GfsVariable * gfs_variable_new (GfsVariableClass * klass,
+				GfsDomain * domain,
+				const gchar * name,
+				const gchar * description)
+{
+  GfsVariable * v;
+
+  g_return_val_if_fail (klass != NULL, NULL);
+  g_return_val_if_fail (domain != NULL, NULL);
+
+  if (name &&
+      (gfs_variable_from_name (domain->variables, name) ||
+       gfs_derived_variable_from_name (domain->derived_variables, name)))
+    return NULL;
+
+  v = GFS_VARIABLE1 (gts_object_new (GTS_OBJECT_CLASS (klass)));
+  if (name)
+    v->name = g_strdup (name);
+  if (description)
+    v->description = g_strdup (description);
+  variable_init_domain (v, domain);
+
+  return v;
+}
+
+/**
+ * gfs_variable_from_name:
+ * @i: the list of available #GfsVariable.
+ * @name: the name of the variable to find.
+ *
+ * Returns: the #GfsVariable @name or %NULL if this variable name does
+ * not exist.  
+ */
+GfsVariable * gfs_variable_from_name (GSList * i,
+				      const gchar * name)
+{
+  g_return_val_if_fail (name != NULL, NULL);
+
+  while (i && (!GFS_VARIABLE1 (i->data)->name || strcmp (name, GFS_VARIABLE1 (i->data)->name)))
+    i = i->next;
+  return i ? GFS_VARIABLE1 (i->data) : NULL;
+}
+
+/**
+ * gfs_variables_from_list:
+ * @i: the list of available #GfsVariable.
+ * @list: a malloc'ed string containing comma separated variable names.
+ * @error: where to return the variable name in case of error.
+ *
+ * Returns: a list of variables or %NULL in case of error, in which
+ * case *@error points to the name of the unknown variable.  
+ */
+GSList * gfs_variables_from_list (GSList * i,
+				  gchar * list,
+				  gchar ** error)
+{
+  gchar * s;
+  GSList * var = NULL;
+
+  g_return_val_if_fail (i != NULL, NULL);
+  g_return_val_if_fail (error != NULL, NULL);
+
+  s = strtok (list, ",");
+  while (s) {
+    GfsVariable * v = gfs_variable_from_name (i, s);
+
+    if (v == NULL) {
+      *error = s;
+      g_slist_free (var);
+      return NULL;
+    }
+    var = g_slist_append (var, v);
+    s = strtok (NULL, ",");
+  }
+  return var;
+}
+
+/**
+ * gfs_variables_swap:
+ * @v1: a #GfsVariable.
+ * @v2: a #GfsVariable.
+ *
+ * Swaps the values of @v1 and @v2, belonging to the same #GfsDomain.
+ */
+void gfs_variables_swap (GfsVariable * v1, GfsVariable * v2)
+{
+  guint i;
+
+  g_return_if_fail (v1 != NULL);
+  g_return_if_fail (v2 != NULL);
+  g_return_if_fail (v1->domain == v2->domain);
+
+  i = v1->i; v1->i = v2->i; v2->i = i;
+}
+
+/**
+ * gfs_variable_set_vector:
+ * @v: the components of the vector.
+ * @n: the vector dimension.
+ *
+ * Sets @v[0],..., at v[n-1] as components of a vector quantity.
+ */
+void gfs_variable_set_vector (GfsVariable ** v, guint n)
+{
+  guint i, j;
+
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (n <= FTT_DIMENSION);
+
+  for (i = 0; i < n; i++) {
+    g_return_if_fail (v[i] != NULL);
+    v[i]->component = i;
+    for (j = 0; j < n; j++)
+      v[i]->vector[j] = v[j];
+  }    
+}
+
+/* GfsVariableTracer: object */
+
+static void variable_tracer_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_tracer_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type == '{')
+    gfs_advection_params_read (&GFS_VARIABLE_TRACER (*o)->advection, fp);
+  if (fp->type != GTS_ERROR && fp->type == '{')
+    g_warning ("%d:%d: specifying diffusion parameters is not done here anymore!",
+	       fp->line, fp->pos);
+}
+
+static void variable_tracer_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_tracer_class ())->parent_class->write) (o, fp);
+
+  fputc (' ', fp);
+  gfs_advection_params_write (&GFS_VARIABLE_TRACER (o)->advection, fp);
+}
+
+static void variable_tracer_class_init (GtsObjectClass * klass)
+{
+  klass->read = variable_tracer_read;
+  klass->write = variable_tracer_write;
+}
+
+static void variable_tracer_init (GfsVariableTracer * v)
+{
+  gfs_advection_params_init (&v->advection);
+  v->advection.gradient = gfs_center_van_leer_gradient;
+  v->advection.flux = gfs_face_advection_flux;
+  v->advection.v = GFS_VARIABLE1 (v);
+  v->advection.fv = NULL;
+  GFS_VARIABLE1 (v)->description = g_strdup ("Tracer");
+}
+
+GfsVariableClass * gfs_variable_tracer_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_tracer_info = {
+      "GfsVariableTracer",
+      sizeof (GfsVariableTracer),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_tracer_class_init,
+      (GtsObjectInitFunc) variable_tracer_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_tracer_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableResidual: Object */
+
+static void scale_residual (FttCell * cell, GfsVariable * res)
+{
+  gdouble size = ftt_cell_size (cell);
+  gdouble dt = GFS_SIMULATION (res->domain)->advection_params.dt;
+  GFS_VARIABLE (cell, res->i) *= dt*dt/(size*size);
+}
+
+static gboolean variable_residual_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_variable_class ())->event) (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) scale_residual, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_residual_class_init (GfsEventClass * klass)
+{
+  klass->event = variable_residual_event;
+}
+
+static void variable_residual_init (GfsVariable * v)
+{
+  v->description = g_strdup ("Residual of the Poisson equation");
+}
+
+GfsVariableClass * gfs_variable_residual_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_residual_info = {
+      "GfsVariableResidual",
+      sizeof (GfsVariable),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_residual_class_init,
+      (GtsObjectInitFunc) variable_residual_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_residual_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableFiltered: object */
+
+static void variable_filtered_read (GtsObject ** o, GtsFile * fp)
+{
+  GfsVariableFiltered * v = GFS_VARIABLE_FILTERED (*o);
+  GfsDomain * domain;
+
+  (* GTS_OBJECT_CLASS (gfs_variable_filtered_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (fp->type != GTS_STRING) {
+    gts_file_error (fp, "expecting a string (v)");
+    return;
+  }
+  domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (!(v->v = gfs_variable_from_name (domain->variables, fp->token->str))) {
+    gts_file_error (fp, "unknown variable `%s'", fp->token->str);
+    return;
+  }
+  gts_file_next_token (fp);
+
+  if (fp->type != GTS_INT) {
+    gts_file_error (fp, "expecting a number (niter)");
+    return;
+  }
+  v->niter = atoi (fp->token->str);
+  if (v->niter == 0) {
+    gts_file_error (fp, "niter must be strictly positive");
+    return;
+  }
+  gts_file_next_token (fp);  
+
+  if (GFS_VARIABLE1 (v)->description)
+    g_free (GFS_VARIABLE1 (v)->description);
+  GFS_VARIABLE1 (v)->description = g_strjoin (" ", "Variable", v->v->name, "filtered", NULL);
+
+  GFS_VARIABLE1 (v)->units = v->v->units;
+}
+
+static void variable_filtered_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_filtered_class ())->parent_class->write) (o, fp);
+
+  fprintf (fp, " %s %d", GFS_VARIABLE_FILTERED (o)->v->name, GFS_VARIABLE_FILTERED (o)->niter);
+}
+
+static void variable_filtered_event_half (GfsEvent * event, GfsSimulation * sim)
+{
+  guint n = GFS_VARIABLE_FILTERED (event)->niter;
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsVariable * v = GFS_VARIABLE1 (event);
+
+  gfs_domain_filter (domain, GFS_VARIABLE_FILTERED (event)->v, v);
+  while (--n)
+    gfs_domain_filter (domain, v, NULL);
+  gfs_domain_cell_traverse (domain,
+			    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) v->fine_coarse, v);
+  gfs_domain_bc (domain, FTT_TRAVERSE_NON_LEAFS, -1, v);
+}
+
+static gboolean variable_filtered_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_filtered_class ())->parent_class)->event)
+      (event, sim)) {
+    variable_filtered_event_half (event, sim);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_filtered_class_init (GtsObjectClass * klass)
+{
+  klass->read = variable_filtered_read;
+  klass->write = variable_filtered_write;
+  GFS_EVENT_CLASS (klass)->event = variable_filtered_event;
+  GFS_EVENT_CLASS (klass)->event_half = variable_filtered_event_half;
+}
+
+static void variable_filtered_init (GfsEvent * v)
+{
+  /* the variable/event may need to be initialised at the start */
+  v->start = -1;
+}
+
+GfsVariableClass * gfs_variable_filtered_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_filtered_info = {
+      "GfsVariableFiltered",
+      sizeof (GfsVariableFiltered),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_filtered_class_init,
+      (GtsObjectInitFunc) variable_filtered_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_filtered_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableDiagonal: object */
+
+static void unity (FttCell * cell, GfsVariable * v)
+{
+  GFS_VARIABLE (cell, v->i) = 1.;
+}
+
+static void variable_diagonal (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsVariable * tmp = data[1];
+  GfsGradient g;
+  FttCellNeighbors neighbor;
+  FttCellFace f;
+  GfsGradient ng;
+
+  GFS_VARIABLE (cell, tmp->i) = G_MAXDOUBLE;
+  g.a = g.b = 0.;
+  f.cell = cell;
+  ftt_cell_neighbors (cell, &neighbor);
+  for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++) {
+    f.neighbor = neighbor.c[f.d];
+    if (f.neighbor) {
+      gfs_face_weighted_gradient (&f, &ng, tmp->i, -1);
+      g.a += ng.a;
+      g.b += ng.b;
+    }
+  }
+  if (g.a > 0.)
+    GFS_VARIABLE (cell, v->i) = g.b/g.a;
+  else
+    GFS_VARIABLE (cell, v->i) = G_MAXDOUBLE;
+  GFS_VARIABLE (cell, tmp->i) = 1.;
+}
+
+static gboolean variable_diagonal_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_diagonal_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    GfsVariable * tmp = gfs_temporary_variable (domain);
+    gpointer data[2];
+    data[0] = event;
+    data[1] = tmp;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) unity, tmp);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, tmp);
+    gfs_poisson_coefficients (domain, sim->physical_params.alpha);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) variable_diagonal, data);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, GFS_VARIABLE1 (event));
+    gts_object_destroy (GTS_OBJECT (tmp));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_diagonal_class_init (GtsObjectClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = variable_diagonal_event;
+}
+
+GfsVariableClass * gfs_variable_diagonal_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_diagonal_info = {
+      "GfsVariableDiagonal",
+      sizeof (GfsVariable),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_diagonal_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_diagonal_info);
+  }
+
+  return klass;
+}
+
+/* GfsVariableFunction: Object */
+
+static void variable_function_destroy (GtsObject * o)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_VARIABLE_FUNCTION (o)->f));
+
+  (* GTS_OBJECT_CLASS (gfs_variable_function_class ())->parent_class->destroy) (o);
+}
+
+static void variable_function_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_function_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsVariableFunction * v = GFS_VARIABLE_FUNCTION (*o);
+  gfs_function_read (v->f, GFS_DOMAIN (gfs_object_simulation (*o)), fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  gfs_function_set_units (v->f, GFS_VARIABLE1 (*o)->units);
+}
+
+static void variable_function_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_function_class ())->parent_class->write) (o, fp);
+
+  gfs_function_write (GFS_VARIABLE_FUNCTION (o)->f, fp);
+}
+
+static void variable_function_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = variable_function_destroy;
+  klass->read = variable_function_read;
+  klass->write = variable_function_write;
+}
+
+static void variable_function_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  GfsFunction * f = GFS_VARIABLE_FUNCTION (v)->f;
+  FttCellChildren child;
+  guint n;
+
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++)
+    if (child.c[n])
+      GFS_VALUE (child.c[n], v) = gfs_function_value (f, child.c[n]);
+}
+
+static void variable_function_init (GfsVariableFunction * v)
+{
+  GFS_VARIABLE1 (v)->coarse_fine = variable_function_coarse_fine;
+  v->f = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsVariableClass * gfs_variable_function_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_function_info = {
+      "GfsVariableFunction",
+      sizeof (GfsVariableFunction),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_function_class_init,
+      (GtsObjectInitFunc) variable_function_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_class ()), 
+				  &gfs_variable_function_info);
+  }
+
+  return klass;
+}
+
+#if FTT_2D
+
+/* GfsVariableStreamFunction: Object */
+
+static gdouble face_metric (FttCell * cell, FttDirection d, GfsDomain * domain)
+{
+  if (domain->face_metric) {
+    FttCellFace f;
+    f.cell = cell;
+    f.d = d;
+    return (* domain->face_metric) (domain, &f);
+  }
+  else
+    return 1.;
+}
+
+static void init_mac_from_stream_function (FttCell * cell,
+					   gdouble psi0, gdouble psi1, gdouble psi2, gdouble psi3,
+					   gdouble h,
+					   GfsDomain * domain,
+					   GfsVariable ** u)
+{
+  GFS_STATE (cell)->f[0].un = (psi2 - psi1)/(h*face_metric (cell, 0, domain));
+  GFS_STATE (cell)->f[1].un = (psi3 - psi0)/(h*face_metric (cell, 1, domain));
+  GFS_STATE (cell)->f[2].un = (psi3 - psi2)/(h*face_metric (cell, 2, domain));
+  GFS_STATE (cell)->f[3].un = (psi0 - psi1)/(h*face_metric (cell, 3, domain));
+
+  GFS_VALUE (cell, u[0]) = (GFS_STATE (cell)->f[0].un + GFS_STATE (cell)->f[1].un)/2.;
+  GFS_VALUE (cell, u[1]) = (GFS_STATE (cell)->f[2].un + GFS_STATE (cell)->f[3].un)/2.;
+}
+
+static void variable_stream_function_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  if (GFS_CELL_IS_BOUNDARY (parent))
+    return;
+
+  GfsFunction * f = GFS_VARIABLE_FUNCTION (v)->f;
+  FttCellChildren child;
+  ftt_cell_children (parent, &child);
+  FttVector o, p;
+  ftt_cell_pos (parent, &o);
+  gdouble h = ftt_cell_size (parent)/2.;
+  p.x = o.x - h; p.y = o.y - h;
+  gdouble psi0 = gfs_function_spatial_value (f, &p);
+  p.x = o.x + h; p.y = o.y - h;
+  gdouble psi1 = gfs_function_spatial_value (f, &p);
+  p.x = o.x + h; p.y = o.y + h;
+  gdouble psi2 = gfs_function_spatial_value (f, &p);
+  p.x = o.x - h; p.y = o.y + h;
+  gdouble psi3 = gfs_function_spatial_value (f, &p);
+  p.x = o.x; p.y = o.y - h;
+  gdouble psi4 = gfs_function_spatial_value (f, &p);
+  p.x = o.x + h; p.y = o.y;
+  gdouble psi5 = gfs_function_spatial_value (f, &p);
+  p.x = o.x; p.y = o.y + h;
+  gdouble psi6 = gfs_function_spatial_value (f, &p);
+  p.x = o.x - h; p.y = o.y;
+  gdouble psi7 = gfs_function_spatial_value (f, &p);
+  gdouble psi8 = gfs_function_spatial_value (f, &o);
+  GfsVariable ** u = gfs_domain_velocity (v->domain);
+  init_mac_from_stream_function (child.c[0], psi7, psi8, psi6, psi3, h, v->domain, u);
+  init_mac_from_stream_function (child.c[1], psi8, psi5, psi2, psi6, h, v->domain, u);
+  init_mac_from_stream_function (child.c[2], psi0, psi4, psi8, psi7, h, v->domain, u);
+  init_mac_from_stream_function (child.c[3], psi4, psi1, psi5, psi8, h, v->domain, u);
+  guint n;
+  for (n = 0; n < FTT_CELLS; n++) {
+    ftt_cell_pos (child.c[n], &o);
+    GFS_VALUE (child.c[n], v) = gfs_function_spatial_value (f, &o);
+  }
+}
+
+static void variable_stream_function_fine_coarse (FttCell * cell, GfsVariable * v)
+{
+  FttCellChildren child;
+  ftt_cell_children (cell, &child);
+  double s = 2.*face_metric (cell, 0, v->domain);
+  GFS_STATE (cell)->f[0].un = 
+    (face_metric (child.c[1], 0, v->domain)*GFS_STATE (child.c[1])->f[0].un +
+     face_metric (child.c[3], 0, v->domain)*GFS_STATE (child.c[3])->f[0].un)/s;
+  s = 2.*face_metric (cell, 1, v->domain);
+  GFS_STATE (cell)->f[1].un = 
+    (face_metric (child.c[0], 1, v->domain)*GFS_STATE (child.c[0])->f[1].un +
+     face_metric (child.c[2], 1, v->domain)*GFS_STATE (child.c[2])->f[1].un)/s;
+  s = 2.*face_metric (cell, 2, v->domain);
+  GFS_STATE (cell)->f[2].un = 
+    (face_metric (child.c[0], 2, v->domain)*GFS_STATE (child.c[0])->f[2].un +
+     face_metric (child.c[1], 2, v->domain)*GFS_STATE (child.c[1])->f[2].un)/s;
+  s = 2.*face_metric (cell, 3, v->domain);
+  GFS_STATE (cell)->f[3].un = 
+    (face_metric (child.c[3], 3, v->domain)*GFS_STATE (child.c[3])->f[3].un +
+     face_metric (child.c[2], 3, v->domain)*GFS_STATE (child.c[2])->f[3].un)/s;
+  GFS_VALUE (cell, v) = (GFS_VALUE (child.c[0], v) + GFS_VALUE (child.c[1], v) + 
+			 GFS_VALUE (child.c[2], v) + GFS_VALUE (child.c[3], v))/4.;
+}
+
+static void init_streamfunction (FttCell * cell, GfsVariable * v)
+{
+  GfsFunction * f = GFS_VARIABLE_FUNCTION (v)->f;
+  FttVector o, p;
+  ftt_cell_pos (cell, &o);
+  gdouble h = ftt_cell_size (cell)/2.;
+  p.x = o.x - h; p.y = o.y - h;
+  gdouble psi0 = gfs_function_spatial_value (f, &p);
+  p.x = o.x + h; p.y = o.y - h;
+  gdouble psi1 = gfs_function_spatial_value (f, &p);
+  p.x = o.x + h; p.y = o.y + h;
+  gdouble psi2 = gfs_function_spatial_value (f, &p);
+  p.x = o.x - h; p.y = o.y + h;
+  gdouble psi3 = gfs_function_spatial_value (f, &p);
+  init_mac_from_stream_function (cell, psi0, psi1, psi2, psi3, 2.*h, 
+				 v->domain, gfs_domain_velocity (v->domain));
+}
+
+static gboolean variable_stream_function_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (gfs_variable_function_class ())->event) (event, sim)) {
+    gfs_domain_traverse_leaves (GFS_DOMAIN (sim), (FttCellTraverseFunc) init_streamfunction, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_stream_function_class_init (GfsEventClass * klass)
+{
+  klass->event = variable_stream_function_event;
+}
+
+static void variable_stream_function_init (GfsVariable * v)
+{
+  v->units = 2.;
+  v->coarse_fine = variable_stream_function_coarse_fine;
+  v->fine_coarse = variable_stream_function_fine_coarse;
+  gts_object_destroy (GTS_OBJECT (GFS_VARIABLE_FUNCTION (v)->f));
+  GFS_VARIABLE_FUNCTION (v)->f = gfs_function_new (gfs_function_spatial_class (), 0.);
+  GFS_EVENT (v)->istep = G_MAXINT/2;
+}
+
+GfsVariableClass * gfs_variable_stream_function_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_stream_function_info = {
+      "GfsVariableStreamFunction",
+      sizeof (GfsVariableFunction),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_stream_function_class_init,
+      (GtsObjectInitFunc) variable_stream_function_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_function_class ()), 
+				  &gfs_variable_stream_function_info);
+  }
+
+  return klass;
+}
+
+#endif /* FTT_2D */
+
+/* GfsDerivedVariable: object */
+
+static void gfs_derived_variable_destroy (GtsObject * object)
+{
+  g_free (GFS_DERIVED_VARIABLE (object)->name);
+  g_free (GFS_DERIVED_VARIABLE (object)->description);
+
+  (* GTS_OBJECT_CLASS (gfs_derived_variable_class ())->parent_class->destroy) (object);
+}
+
+static void gfs_derived_variable_class_init (GtsObjectClass * klass)
+{
+  klass->destroy = gfs_derived_variable_destroy;
+}
+
+GtsObjectClass * gfs_derived_variable_class (void)
+{
+  static GtsObjectClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_derived_variable_info = {
+      "GfsDerivedVariable",
+      sizeof (GfsDerivedVariable),
+      sizeof (GtsObjectClass),
+      (GtsObjectClassInitFunc) gfs_derived_variable_class_init,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_object_class ()), 
+				  &gfs_derived_variable_info);
+  }
+
+  return klass;
+}
+
+/**
+ * gfs_derived_variable_from_name:
+ * @i: a list of #GfsDerivedVariable.
+ * @name: a name.
+ *
+ * Returns: the #GfsDerivedVariable @name of @list or %NULL.
+ */
+GfsDerivedVariable * gfs_derived_variable_from_name (GSList * i, const gchar * name)
+{
+  g_return_val_if_fail (name != NULL, NULL);
+
+  while (i) {
+    GfsDerivedVariable * v = i->data;
+    if (!strcmp (v->name, name))
+      return v;
+    i = i->next;
+  }
+  return NULL;
+}
diff --git a/src/variable.h b/src/variable.h
new file mode 100644
index 0000000..dce3566
--- /dev/null
+++ b/src/variable.h
@@ -0,0 +1,199 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __VARIABLE_H__
+#define __VARIABLE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GfsSurfaceGenericBc        GfsSurfaceGenericBc;
+
+#include "timestep.h"
+#include "event.h"
+
+/* GfsVariable: Header */
+
+typedef void (* GfsVariableFineCoarseFunc) (FttCell * cell, GfsVariable * v);
+
+struct _GfsVariable {
+  /*< private >*/
+  GfsEvent parent;
+
+  /*< public >*/
+  guint i;
+  FttComponent component;
+  GfsVariable * vector[FTT_DIMENSION];
+  gchar * name, * description;
+  gboolean centered;
+  GfsVariableFineCoarseFunc fine_coarse, coarse_fine;
+  GtsContainer * sources;
+  GfsSurfaceGenericBc * surface_bc;
+  GfsBc * default_bc;
+  GfsDomain * domain;
+  FttCellCleanupFunc cleanup;
+  gdouble units;
+};
+
+typedef struct _GfsVariableClass    GfsVariableClass;
+
+struct _GfsVariableClass {
+  /*< private >*/
+  GfsEventClass parent_class;
+
+  /*< public >*/
+};
+
+#define GFS_VARIABLE1(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsVariable,\
+					         gfs_variable_class ())
+#define GFS_VARIABLE_CLASS(klass)    GTS_OBJECT_CLASS_CAST (klass,\
+						 GfsVariableClass,\
+						 gfs_variable_class())
+#define GFS_IS_VARIABLE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_variable_class ()))
+#define GFS_VALUE(cell,v)            ((&GFS_STATE (cell)->place_holder)[(v)->i])
+
+GfsVariableClass *    gfs_variable_class            (void);
+GfsVariable *         gfs_variable_new              (GfsVariableClass * klass,
+						     GfsDomain * domain,
+						     const gchar * name,
+						     const gchar * description);
+#define               gfs_temporary_variable(d)     (gfs_variable_new (gfs_variable_class (),\
+                                                                      (d), NULL, NULL))
+GfsVariable *         gfs_variable_from_name        (GSList * i,
+						     const gchar * name);
+GSList *              gfs_variables_from_list       (GSList * i,
+						     gchar * list,
+						     gchar ** error);
+void                  gfs_variables_swap            (GfsVariable * v1, 
+						     GfsVariable * v2);
+void                  gfs_variable_set_vector       (GfsVariable ** v,
+						     guint n);
+
+/* GfsVariableTracer: header */
+
+typedef struct _GfsVariableTracer                GfsVariableTracer;
+
+struct _GfsVariableTracer {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsAdvectionParams advection;
+};
+
+#define GFS_VARIABLE_TRACER(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableTracer,\
+					           gfs_variable_tracer_class ())
+#define GFS_IS_VARIABLE_TRACER(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_tracer_class ()))
+
+GfsVariableClass * gfs_variable_tracer_class  (void);
+
+/* GfsVariableResidual: header */
+
+#define GFS_IS_VARIABLE_RESIDUAL(obj)         (gts_object_is_from_class (obj,\
+					       gfs_variable_residual_class ()))
+
+GfsVariableClass * gfs_variable_residual_class  (void);
+
+/* GfsVariableFiltered: header */
+
+typedef struct _GfsVariableFiltered                GfsVariableFiltered;
+
+struct _GfsVariableFiltered {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsVariable * v;
+  guint niter;
+};
+
+#define GFS_VARIABLE_FILTERED(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableFiltered,\
+					           gfs_variable_filtered_class ())
+#define GFS_IS_VARIABLE_FILTERED(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_filtered_class ()))
+
+GfsVariableClass * gfs_variable_filtered_class  (void);
+
+/* GfsVariableDiagonal: Header */
+
+GfsVariableClass * gfs_variable_diagonal_class  (void);
+
+/* GfsVariableFunction: header */
+
+typedef struct _GfsVariableFunction                GfsVariableFunction;
+
+struct _GfsVariableFunction {
+  /*< private >*/
+  GfsVariable parent;
+
+  /*< public >*/
+  GfsFunction * f;
+};
+
+#define GFS_VARIABLE_FUNCTION(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableFunction,\
+					           gfs_variable_function_class ())
+#define GFS_IS_VARIABLE_FUNCTION(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_function_class ()))
+
+GfsVariableClass * gfs_variable_function_class  (void);
+
+#if FTT_2D
+
+/* GfsVariableStreamFunction: header */
+
+#define GFS_IS_VARIABLE_STREAM_FUNCTION(obj)         (gts_object_is_from_class (obj,\
+					     gfs_variable_stream_function_class ()))
+
+GfsVariableClass * gfs_variable_stream_function_class  (void);
+
+#endif /* FTT_2D */
+
+/* GfsDerivedVariable: Header */
+
+struct _GfsDerivedVariable {
+  /*< private >*/
+  GtsObject parent;
+
+  /*< public >*/
+  gchar * name, * description;
+  gpointer func, data;
+};
+
+#define GFS_DERIVED_VARIABLE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsDerivedVariable,\
+					         gfs_derived_variable_class ())
+#define GFS_IS_DERIVED_VARIABLE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_derived_variable_class ()))
+
+GtsObjectClass *     gfs_derived_variable_class            (void);
+GfsDerivedVariable * gfs_derived_variable_from_name        (GSList * i, 
+							    const gchar * name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __VARIABLE_H__ */
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..ed5551f
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,11 @@
+/* version.h
+ *
+ * This is a generated file.  Please modify 'darcsversion.sh'
+ */
+
+#ifndef GFSVERSION_H
+#define GFSVERSION_H
+
+#define GFS_BUILD_VERSION "091110-141005"
+
+#endif /* GFSVERSION_H */
diff --git a/src/vof.c b/src/vof.c
new file mode 100644
index 0000000..90b7e32
--- /dev/null
+++ b/src/vof.c
@@ -0,0 +1,2412 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include "vof.h"
+#include "variable.h"
+#include "adaptive.h"
+#include "graphic.h"
+
+#define THRESHOLD(c) {if ((c) < 0.) c = 0.; else if ((c) > 1.) c = 1.;}
+
+/**
+ * gfs_line_area:
+ * @m: normal to the line.
+ * @alpha: line constant.
+ *
+ * Returns: the area of the fraction of a cell lying under the line
+ * (@m, at alpha).
+ */
+gdouble gfs_line_area (const FttVector * m, gdouble alpha)
+{
+  FttVector n;
+  gdouble alpha1, a, v, area;
+
+  g_return_val_if_fail (m != NULL, 0.);
+
+  n = *m;
+  alpha1 = alpha;
+  if (n.x < 0.) {
+    alpha1 -= n.x;
+    n.x = - n.x;
+  }
+  if (n.y < 0.) {
+    alpha1 -= n.y;
+    n.y = - n.y;
+  }
+
+  if (alpha1 <= 0.)
+    return 0.;
+
+  if (alpha1 >= n.x + n.y)
+    return 1.;
+
+  if (n.x == 0.)
+    area = alpha1/n.y;
+  else if (n.y == 0.)
+    area = alpha1/n.x;
+  else {
+    v = alpha1*alpha1;
+
+    a = alpha1 - n.x;
+    if (a > 0.)
+      v -= a*a;
+    
+    a = alpha1 - n.y;
+    if (a > 0.)
+      v -= a*a;
+
+    area = v/(2.*n.x*n.y);
+  }
+
+  return CLAMP (area, 0., 1.);
+}
+
+/**
+ * gfs_line_alpha:
+ * @m: a #FttVector.
+ * @c: a volume fraction.
+ *
+ * Returns: the value @alpha such that the area of a square cell
+ * lying under the line defined by @m. at x = @alpha is equal to @c. 
+ */
+gdouble gfs_line_alpha (const FttVector * m, gdouble c)
+{
+  gdouble alpha, m1, m2, v1;
+
+  g_return_val_if_fail (m != NULL, 0.);
+  g_return_val_if_fail (c >= 0. && c <= 1., 0.);
+  
+  m1 = fabs (m->x); m2 = fabs (m->y);
+  if (m1 > m2) {
+    v1 = m1; m1 = m2; m2 = v1;
+  }
+  
+  v1 = m1/2.;
+  if (c <= v1/m2)
+    alpha = sqrt (2.*c*m1*m2);
+  else if (c <= 1. - v1/m2)
+    alpha = c*m2 + v1;
+  else
+    alpha = m1 + m2 - sqrt (2.*m1*m2*(1. - c));
+
+  if (m->x < 0.)
+    alpha += m->x;
+  if (m->y < 0.)
+    alpha += m->y;
+
+  return alpha;
+}
+
+#define EPS 1e-4
+
+/**
+ * gfs_line_center:
+ * @m: normal to the line.
+ * @alpha: line constant.
+ * @a: area of cell fraction.
+ * @p: a #FttVector.
+ *
+ * Fills @p with the position of the center of mass of the fraction of
+ * a square cell lying under the line (@m, at alpha).
+ */
+void gfs_line_center (const FttVector * m, gdouble alpha, gdouble a, FttVector * p)
+{
+  FttVector n;
+  gdouble b;
+
+  g_return_if_fail (m != NULL);
+  g_return_if_fail (p != NULL);
+
+  n = *m;
+  if (n.x < 0.) {
+    alpha -= n.x;
+    n.x = - n.x;
+  }
+  if (n.y < 0.) {
+    alpha -= n.y;
+    n.y = - n.y;
+  }
+
+  p->z = 0.;
+  if (alpha <= 0.) {
+    p->x = p->y = 0.;
+    return;
+  }
+
+  if (alpha >= n.x + n.y) {
+    p->x = p->y = 0.5;
+    return;
+  }
+
+  g_return_if_fail (a > 0. && a < 1.);
+
+  if (n.x < EPS) {
+    p->x = 0.5;
+    p->y = m->y < 0. ? 1. - a/2. : a/2.;
+    return;
+  }
+
+  if (n.y < EPS) {
+    p->y = 0.5;
+    p->x = m->x < 0. ? 1. - a/2. : a/2.;
+    return;
+  }
+
+  p->x = p->y = alpha*alpha*alpha;
+
+  b = alpha - n.x;
+  if (b > 0.) {
+    p->x -= b*b*(alpha + 2.*n.x);
+    p->y -= b*b*b;
+  }
+
+  b = alpha - n.y;
+  if (b > 0.) {
+    p->y -= b*b*(alpha + 2.*n.y);
+    p->x -= b*b*b;
+  }
+  
+  p->x /= 6.*n.x*n.x*n.y*a;
+  p->y /= 6.*n.x*n.y*n.y*a;
+
+  if (m->x < 0.)
+    p->x = 1. - p->x;
+  if (m->y < 0.)
+    p->y = 1. - p->y;
+}
+
+/**
+ * gfs_line_area_center:
+ * @m: normal to the line.
+ * @alpha: line constant.
+ * @p: a #FttVector.
+ *
+ * Fills @p with the position of the center of area of the fraction of
+ * a square cell lying under the line (@m, at alpha).
+ *
+ * Returns: the length of the facet.
+ */
+gdouble gfs_line_area_center (const FttVector * m, gdouble alpha, FttVector * p)
+{
+  FttVector n;
+
+  g_return_val_if_fail (m != NULL, 0.);
+  g_return_val_if_fail (p != NULL, 0.);
+
+  n = *m;
+  if (n.x < 0.) {
+    alpha -= n.x;
+    n.x = - n.x;
+  }
+  if (n.y < 0.) {
+    alpha -= n.y;
+    n.y = - n.y;
+  }
+
+  p->z = 0.;
+  if (alpha <= 0. || alpha >= n.x + n.y) {
+    p->x = p->y = 0.;
+    return 0.;
+  }
+
+  if (n.x < EPS) {
+    p->x = 0.5;
+    p->y = m->y < 0. ? 1. - alpha : alpha;
+    return 1.;
+  }
+
+  if (n.y < EPS) {
+    p->y = 0.5;
+    p->x = m->x < 0. ? 1. - alpha : alpha;
+    return 1.;
+  }
+
+  p->x = p->y = 0.;
+
+  if (alpha >= n.x) {
+    p->x += 1.;
+    p->y += (alpha - n.x)/n.y;
+  }
+  else
+    p->x += alpha/n.x;
+
+  gdouble ax = p->x, ay = p->y;
+  if (alpha >= n.y) {
+    p->y += 1.;
+    ay -= 1.;
+    p->x += (alpha - n.y)/n.x;
+    ax -= (alpha - n.y)/n.x;
+  }
+  else {
+    p->y += alpha/n.y;
+    ay -= alpha/n.y;
+  }
+
+  p->x /= 2.;
+  p->y /= 2.;
+
+  THRESHOLD (p->x);
+  THRESHOLD (p->y);
+
+  if (m->x < 0.)
+    p->x = 1. - p->x;
+  if (m->y < 0.)
+    p->y = 1. - p->y;
+
+  return sqrt (ax*ax + ay*ay);
+}
+
+#if (!FTT_2D)
+/**
+ * gfs_plane_volume:
+ * @m: normal to the plane.
+ * @alpha: plane constant.
+ *
+ * Returns: the volume of a cell lying under the plane (@m, at alpha).
+ */
+gdouble gfs_plane_volume (const FttVector * m, gdouble alpha)
+{
+  g_return_val_if_fail (m != NULL, 0.);
+
+  gdouble al = alpha + MAX(0., -m->x) + MAX(0., -m->y) + MAX(0., -m->z);
+  if (al <= 0.)
+    return 0.;
+  gdouble tmp = fabs(m->x) + fabs(m->y) + fabs(m->z);
+  if (al >= tmp)
+    return 1.;
+  g_assert (tmp > 0.);
+  gdouble n1 = fabs(m->x)/tmp;
+  gdouble n2 = fabs(m->y)/tmp;
+  gdouble n3 = fabs(m->z)/tmp;
+  al = MAX(0., MIN(1., al/tmp));
+  gdouble al0 = MIN(al, 1. - al);
+  gdouble b1 = MIN(n1*1, n2);
+  gdouble b3 = MAX(n1*1, n2);
+  gdouble b2 = n3;
+  if (b2 < b1) {
+    tmp = b1;
+    b1 = b2;
+    b2 = tmp;
+  }
+  else if (b2 > b3) {
+    tmp = b3;
+    b3 = b2;
+    b2 = tmp;
+  }
+  gdouble b12 = b1 + b2;
+  gdouble bm = MIN(b12, b3);
+  gdouble pr = MAX(6.*b1*b2*b3, 1e-50);
+  if (al0 < b1)
+    tmp = al0*al0*al0/pr;
+  else if (al0 < b2)
+    tmp = 0.5*al0*(al0 - b1)/(b2*b3) +  b1*b1*b1/pr;
+  else if (al0 < bm)
+    tmp = (al0*al0*(3.*b12 - al0) + b1*b1*(b1 - 3.*al0) + b2*b2*(b2 - 3.*al0))/pr;
+  else if (b12 < b3)
+    tmp = (al0 - 0.5*bm)/b3;
+  else
+    tmp = (al0*al0*(3. - 2.*al0) + b1*b1*(b1 - 3.*al0) + 
+	   b2*b2*(b2 - 3.*al0) + b3*b3*(b3 - 3.*al0))/pr;
+
+  gdouble volume = al <= 0.5 ? tmp : 1. - tmp;
+  return CLAMP (volume, 0., 1.);
+}
+
+/**
+ * gfs_plane_alpha:
+ * @m: a #FttVector.
+ * @c: a volume fraction.
+ *
+ * Returns: the value @alpha such that the volume of a cubic cell
+ * lying under the plane defined by @m. at x = @alpha is equal to @c. 
+ */
+gdouble gfs_plane_alpha (const FttVector * m, gdouble c)
+{
+  gdouble alpha;
+  FttVector n;
+
+  g_return_val_if_fail (m != NULL, 0.);
+  g_return_val_if_fail (c >= 0. && c <= 1., 0.);
+
+  n.x = fabs (m->x); n.y = fabs (m->y); n.z = fabs (m->z);
+
+  gdouble m1, m2, m3;
+  m1 = MIN(n.x, n.y);
+  m3 = MAX(n.x, n.y);
+  m2 = n.z;
+  if (m2 < m1) {
+    gdouble tmp = m1;
+    m1 = m2;
+    m2 = tmp;
+  }
+  else if (m2 > m3) {
+    gdouble tmp = m3;
+    m3 = m2;
+    m2 = tmp;
+  }
+  gdouble m12 = m1 + m2;
+  gdouble pr = MAX(6.*m1*m2*m3, 1e-50);
+  gdouble V1 = m1*m1*m1/pr;
+  gdouble V2 = V1 + (m2 - m1)/(2.*m3), V3;
+  gdouble mm;
+  if (m3 < m12) {
+    mm = m3;
+    V3 = (m3*m3*(3.*m12 - m3) + m1*m1*(m1 - 3.*m3) + m2*m2*(m2 - 3.*m3))/pr;
+  }
+  else {
+    mm = m12;
+    V3 = mm/(2.*m3);
+  }
+
+  gdouble ch = MIN(c, 1. - c);
+  if (ch < V1)
+    alpha = pow (pr*ch, 1./3.);
+  else if (ch < V2)
+    alpha = (m1 + sqrt(m1*m1 + 8.*m2*m3*(ch - V1)))/2.;
+  else if (ch < V3) {
+    gdouble p = 2.*m1*m2;
+    gdouble q = 3.*m1*m2*(m12 - 2.*m3*ch)/2.;
+    gdouble p12 = sqrt (p);
+    gdouble teta = acos(q/(p*p12))/3.;
+    gdouble cs = cos(teta);
+    alpha = p12*(sqrt(3.*(1. - cs*cs)) - cs) + m12;
+  }
+  else if (m12 < m3)
+    alpha = m3*ch + mm/2.;
+  else {
+    gdouble p = m1*(m2 + m3) + m2*m3 - 1./4.;
+    gdouble q = 3.*m1*m2*m3*(1./2. - ch)/2.;
+    gdouble p12 = sqrt(p);
+    gdouble teta = acos(q/(p*p12))/3.;
+    gdouble cs = cos(teta);
+    alpha = p12*(sqrt(3.*(1. - cs*cs)) - cs) + 1./2.;
+  }
+  if (c > 1./2.) alpha = 1. - alpha;
+
+  if (m->x < 0.)
+    alpha += m->x;
+  if (m->y < 0.)
+    alpha += m->y;
+  if (m->z < 0.)
+    alpha += m->z;
+
+  return alpha;
+}
+
+/**
+ * gfs_plane_center:
+ * @m: normal to the plane.
+ * @alpha: plane constant.
+ * @a: volume of cell fraction.
+ * @p: a #FttVector.
+ *
+ * Fills @p with the position of the center of mass of the fraction of
+ * a cubic cell lying under the plane (@m, at alpha).
+ */
+void gfs_plane_center (const FttVector * m, gdouble alpha, gdouble a, FttVector * p)
+{
+  FttVector n;
+  gdouble b, amax;
+
+  g_return_if_fail (m != NULL);
+  g_return_if_fail (p != NULL);
+  g_return_if_fail (a >= 0. && a <= 1.);
+
+  if (fabs (m->x) < EPS) {
+    FttVector q;
+    n.x = m->y;
+    n.y = m->z;
+    gfs_line_center (&n, alpha, a, &q);
+    p->x = 0.5;
+    p->y = q.x;
+    p->z = q.y;
+    return;
+  }
+  if (fabs (m->y) < EPS) {
+    FttVector q;
+    n.x = m->z;
+    n.y = m->x;
+    gfs_line_center (&n, alpha, a, &q);
+    p->x = q.y;
+    p->y = 0.5;
+    p->z = q.x;
+    return;
+  }
+  if (fabs (m->z) < EPS) {
+    gfs_line_center (m, alpha, a, p);
+    p->z = 0.5;
+    return;
+  }
+
+  n = *m;
+  if (n.x < 0.) {
+    alpha -= n.x;
+    n.x = - n.x;
+  }
+  if (n.y < 0.) {
+    alpha -= n.y;
+    n.y = - n.y;
+  }  
+  if (n.z < 0.) {
+    alpha -= n.z;
+    n.z = - n.z;
+  }  
+
+  if (alpha <= 0. || a == 0.) {
+    p->x = p->y = p->z = 0.;
+    return;
+  }
+
+  if (alpha >= n.x + n.y + n.z || a == 1.) {
+    p->x = p->y = p->z = 0.5;
+    return;
+  }
+
+  amax = n.x + n.y + n.z;
+  p->x = p->y = p->z = alpha*alpha*alpha*alpha;
+
+  b = alpha - n.x;
+  if (b > 0.) {
+    p->x -= b*b*b*(3.*n.x + alpha);
+    p->y -= b*b*b*b;
+    p->z -= b*b*b*b;
+  }
+  b = alpha - n.y;
+  if (b > 0.) {
+    p->y -= b*b*b*(3.*n.y + alpha);
+    p->x -= b*b*b*b;
+    p->z -= b*b*b*b;
+  }
+  b = alpha - n.z;
+  if (b > 0.) {
+    p->z -= b*b*b*(3.*n.z + alpha);
+    p->x -= b*b*b*b;
+    p->y -= b*b*b*b;
+  }
+
+  amax = alpha - amax;
+  b = amax + n.x;
+  if (b > 0.) {
+    p->y += b*b*b*(3.*n.y + alpha - n.z);
+    p->z += b*b*b*(3.*n.z + alpha - n.y);
+    p->x += b*b*b*b;
+  }
+  b = amax + n.y;
+  if (b > 0.) {
+    p->x += b*b*b*(3.*n.x + alpha - n.z);
+    p->z += b*b*b*(3.*n.z + alpha - n.x);
+    p->y += b*b*b*b;
+  }
+  b = amax + n.z;
+  if (b > 0.) {
+    p->x += b*b*b*(3.*n.x + alpha - n.y);
+    p->y += b*b*b*(3.*n.y + alpha - n.x);
+    p->z += b*b*b*b;
+  }
+
+  b = 24.*n.x*n.y*n.z*a;
+  p->x /= b*n.x; p->y /= b*n.y; p->z /= b*n.z;
+
+  if (m->x < 0.) p->x = 1. - p->x;
+  if (m->y < 0.) p->y = 1. - p->y;
+  if (m->z < 0.) p->z = 1. - p->z;
+}
+
+/**
+ * gfs_plane_area_center:
+ * @m: normal to the plane.
+ * @alpha: plane constant.
+ * @p: a #FttVector.
+ *
+ * Fills @p with the position of the center of area of the fraction of
+ * a cubic cell lying under the plane (@m, at alpha).
+ *
+ * Returns: the area of the facet.
+ */
+gdouble gfs_plane_area_center (const FttVector * m, gdouble alpha, FttVector * p)
+{
+  g_return_val_if_fail (m != NULL, 0.);
+  g_return_val_if_fail (p != NULL, 0.);
+
+  if (fabs (m->x) < EPS) {
+    FttVector n, q;
+    n.x = m->y;
+    n.y = m->z;
+    gdouble area = gfs_line_area_center (&n, alpha, &q);
+    p->x = 0.5;
+    p->y = q.x;
+    p->z = q.y;
+    return area;
+  }
+  if (fabs (m->y) < EPS) {
+    FttVector n, q;
+    n.x = m->z;
+    n.y = m->x;
+    gdouble area = gfs_line_area_center (&n, alpha, &q);
+    p->x = q.y;
+    p->y = 0.5;
+    p->z = q.x;
+    return area;
+  }
+  if (fabs (m->z) < EPS) {
+    gdouble area = gfs_line_area_center (m, alpha, p);
+    p->z = 0.5;
+    return area;
+  }
+
+  FttVector n = *m;
+  if (n.x < 0.) {
+    alpha -= n.x;
+    n.x = - n.x;
+  }
+  if (n.y < 0.) {
+    alpha -= n.y;
+    n.y = - n.y;
+  }  
+  if (n.z < 0.) {
+    alpha -= n.z;
+    n.z = - n.z;
+  }
+
+  gdouble amax = n.x + n.y + n.z;
+  if (alpha <= 0. || alpha >= amax) {
+    p->x = p->y = p->z = 0.;
+    return 0.;
+  }
+
+  gdouble area = alpha*alpha;
+  p->x = p->y = p->z = area*alpha;
+
+  gdouble b = alpha - n.x;
+  if (b > 0.) {
+    area -= b*b;
+    p->x -= b*b*(2.*n.x + alpha);
+    p->y -= b*b*b;
+    p->z -= b*b*b;
+  }
+  b = alpha - n.y;
+  if (b > 0.) {
+    area -= b*b;
+    p->y -= b*b*(2.*n.y + alpha);
+    p->x -= b*b*b;
+    p->z -= b*b*b;
+  }
+  b = alpha - n.z;
+  if (b > 0.) {
+    area -= b*b;
+    p->z -= b*b*(2.*n.z + alpha);
+    p->x -= b*b*b;
+    p->y -= b*b*b;
+  }
+
+  amax = alpha - amax;
+  b = amax + n.x;
+  if (b > 0.) {
+    area += b*b;
+    p->y += b*b*(2.*n.y + alpha - n.z);
+    p->z += b*b*(2.*n.z + alpha - n.y);
+    p->x += b*b*b;
+  }
+  b = amax + n.y;
+  if (b > 0.) {
+    area += b*b;
+    p->x += b*b*(2.*n.x + alpha - n.z);
+    p->z += b*b*(2.*n.z + alpha - n.x);
+    p->y += b*b*b;
+  }
+  b = amax + n.z;
+  if (b > 0.) {
+    area += b*b;
+    p->x += b*b*(2.*n.x + alpha - n.y);
+    p->y += b*b*(2.*n.y + alpha - n.x);
+    p->z += b*b*b;
+  }
+
+  area *= 3.;
+  p->x /= area*n.x;
+  p->y /= area*n.y;
+  p->z /= area*n.z;
+
+  THRESHOLD (p->x);
+  THRESHOLD (p->y);
+  THRESHOLD (p->z);
+
+  if (m->x < 0.) p->x = 1. - p->x;
+  if (m->y < 0.) p->y = 1. - p->y;
+  if (m->z < 0.) p->z = 1. - p->z;
+
+  return area*sqrt (1./(n.x*n.x*n.y*n.y) + 1./(n.x*n.x*n.z*n.z) + 1./(n.z*n.z*n.y*n.y))/6.;
+}
+#endif /* 3D */
+
+/**
+ * gfs_youngs_gradient:
+ * @cell: a #FttCell.
+ * @v: a #GfsVariable.
+ * @g: a #FttVector.
+ *
+ * Fills @g with the Youngs-averaged gradients of @v 
+ * normalised by the size of @cell.
+ */
+void gfs_youngs_gradient (FttCell * cell, GfsVariable * v, FttVector * g)
+{
+  static FttDirection d[(FTT_DIMENSION - 1)*4][FTT_DIMENSION] = {
+#if FTT_2D
+    {FTT_RIGHT, FTT_TOP}, {FTT_LEFT, FTT_TOP}, {FTT_LEFT, FTT_BOTTOM}, {FTT_RIGHT, FTT_BOTTOM}
+#else  /* 3D */
+    {FTT_RIGHT, FTT_TOP, FTT_FRONT}, {FTT_LEFT, FTT_TOP, FTT_FRONT}, 
+    {FTT_LEFT, FTT_BOTTOM, FTT_FRONT}, {FTT_RIGHT, FTT_BOTTOM, FTT_FRONT},
+    {FTT_RIGHT, FTT_TOP, FTT_BACK}, {FTT_LEFT, FTT_TOP, FTT_BACK}, 
+    {FTT_LEFT, FTT_BOTTOM, FTT_BACK}, {FTT_RIGHT, FTT_BOTTOM, FTT_BACK},
+#endif /* 3D */
+  };
+  gdouble u[(FTT_DIMENSION - 1)*4];
+  guint i;
+
+  g_return_if_fail (cell != NULL);
+  g_return_if_fail (v != NULL);
+  g_return_if_fail (g != NULL);
+
+  for (i = 0; i < (FTT_DIMENSION - 1)*4; i++)
+    u[i] = gfs_cell_corner_value (cell, d[i], v, -1);
+
+#if FTT_2D
+  g->x = (u[0] + u[3] - u[1] - u[2])/2.;
+  g->y = (u[0] + u[1] - u[2] - u[3])/2.;
+#else  /* 3D */
+  g->x = (u[0] + u[3] + u[4] + u[7] - u[1] - u[2] - u[5] - u[6])/4.;
+  g->y = (u[0] + u[1] + u[4] + u[5] - u[2] - u[3] - u[6] - u[7])/4.;
+  g->z = (u[0] + u[1] + u[2] + u[3] - u[4] - u[5] - u[6] - u[7])/4.;
+#endif /* 3D */
+}
+
+/**
+ * gfs_vof_plane_interpolate:
+ * @cell: a #FttCell containing location @p.
+ * @p: the center of the virtual cell.
+ * @level: the level of the virtual cell.
+ * @t: a #GfsVariableTracerVOF.
+ * @m: a #FttVector.
+ *
+ * Computes the equation @m.x = alpha of the volume fraction plane of
+ * a virtual cell at @level centered on @p.
+ *
+ * Returns: alpha for the virtual cell.
+ */
+gdouble gfs_vof_plane_interpolate (FttCell * cell,
+				   FttVector * p,
+				   guint level,
+				   GfsVariableTracerVOF * t,
+				   FttVector * m)
+{
+  guint l = ftt_cell_level (cell);
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (l <= level, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+  g_return_val_if_fail (m != NULL, 0.);
+
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  gdouble f = GFS_VALUE (cell, v);
+  g_return_val_if_fail (!GFS_IS_FULL (f), 0.);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m->x)[c] = GFS_VALUE (cell, t->m[c]);
+
+  gdouble alpha = GFS_VALUE (cell, t->alpha);
+  if (l < level) {
+    gdouble h = ftt_level_size (level);
+    gdouble H = ftt_cell_size (cell);
+    FttVector q;
+    
+    ftt_cell_pos (cell, &q);
+    alpha *= H;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      alpha -= (&m->x)[c]*((&p->x)[c] - h/2. - (&q.x)[c] + H/2);
+    alpha /= h;
+  }
+  return alpha;
+}
+
+/**
+ * gfs_vof_interpolate:
+ * @cell: a #FttCell containing location @p.
+ * @p: the center of the virtual cell.
+ * @level: the level of the virtual cell.
+ * @t: a #GfsVariableTracerVOF.
+ *
+ * Computes the volume fraction of a virtual cell at @level centered
+ * on @p.
+ *
+ * Returns: the volume fraction of the virtual cell.
+ */
+gdouble gfs_vof_interpolate (FttCell * cell,
+			     FttVector * p,
+			     guint level,
+			     GfsVariableTracerVOF * t)
+{
+  guint l = ftt_cell_level (cell);
+
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (l <= level, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  gdouble f = GFS_VALUE (cell, v);
+  if (l == level || GFS_IS_FULL (f))
+    return f;
+  else {
+    FttVector m;
+    gdouble alpha = gfs_vof_plane_interpolate (cell, p, level, t, &m);
+    return gfs_plane_volume (&m, alpha);
+  }
+}
+
+/* GfsVariableTracerVOF: object */
+
+#if FTT_2D
+# define F(x,y,z) f[x][y]
+#else
+# define F(x,y,z) f[x][y][z]
+#endif
+
+static void stencil (FttCell * cell, GfsVariable * v, gdouble F(3,3,3))
+{
+  gdouble h = ftt_cell_size (cell);
+  guint level = ftt_cell_level (cell);
+  FttVector p;
+  gint x, y, z = 0;
+  
+  F(1,1,1) = GFS_VALUE (cell, v);
+  ftt_cell_pos (cell, &p);
+#if !FTT_2D
+  for (z = -1; z <= 1; z++)
+#endif
+    for (x = -1; x <= 1; x++)
+      for (y = -1; y <= 1; y++)
+	if (x != 0 || y != 0 || z != 0) {
+	  FttVector o;
+	  o.x = p.x + h*x; o.y = p.y + h*y; o.z = p.z + h*z;
+	  FttCell * neighbor = gfs_domain_boundary_locate (v->domain, o, level, NULL);
+	  if (neighbor)
+	    F(x + 1, y + 1, z + 1) =
+	      gfs_vof_interpolate (neighbor, &o, level, GFS_VARIABLE_TRACER_VOF (v));
+	  else
+	    F(x + 1, y + 1, z + 1) = -1.;
+	}
+  /* boundary conditions (symmetry) */
+#if FTT_2D
+  for (x = 0; x <= 2; x++) {
+    if (f[x][0] < 0.) f[x][0] = f[x][1];
+    if (f[x][2] < 0.) f[x][2] = f[x][1];
+  }
+  for (y = 0; y <= 2; y++) {
+    if (f[0][y] < 0.) f[0][y] = f[1][y];
+    if (f[2][y] < 0.) f[2][y] = f[1][y];
+  }
+#else /* 3D */
+  for (x = 0; x <= 2; x++)
+    for (y = 0; y <= 2; y++) {
+      if (f[x][y][0] < 0.) f[x][y][0] = f[x][y][1];
+      if (f[x][y][2] < 0.) f[x][y][2] = f[x][y][1];
+    }
+  for (x = 0; x <= 2; x++)
+    for (z = 0; z <= 2; z++) {
+      if (f[x][0][z] < 0.) f[x][0][z] = f[x][1][z];
+      if (f[x][2][z] < 0.) f[x][2][z] = f[x][1][z];
+    }
+  for (z = 0; z <= 2; z++)
+    for (y = 0; y <= 2; y++) {
+      if (f[0][y][z] < 0.) f[0][y][z] = f[1][y][z];
+      if (f[2][y][z] < 0.) f[2][y][z] = f[1][y][z];
+    }
+#endif /* 3D */
+}
+
+static void youngs_normal (FttCell * cell, GfsVariable * v, FttVector * n)
+{
+  gdouble F(3,3,3);
+
+  stencil (cell, v, f);
+#if FTT_2D
+  n->x = (f[0][2] + 2.*f[0][1] + f[0][0] - 2.*f[2][1] - f[2][2] - f[2][0])/8.;
+  n->y = (f[2][0] + 2.*f[1][0] + f[0][0] - 2.*f[1][2] - f[2][2] - f[0][2])/8.;
+  n->z = 0.;
+#else  /* 3D */
+  gdouble mm1 = f[0][0][0] + f[0][0][2] + f[0][2][0] + f[0][2][2] +
+    2.*(f[0][0][1] + f[0][2][1] + f[0][1][0] + f[0][1][2]) + 
+    4.*f[0][1][1];
+  gdouble mm2 = f[2][0][0] + f[2][0][2] + f[2][2][0] + f[2][2][2] + 
+    2.*(f[2][0][1] + f[2][2][1] + f[2][1][0] + f[2][1][2]) + 
+    4.*f[2][1][1];
+  n->x = (mm1 - mm2)/32.;
+    
+  mm1 = f[0][0][0] + f[0][0][2] + f[2][0][0] + f[2][0][2] + 
+    2.*(f[0][0][1] + f[2][0][1] + f[1][0][0] + f[1][0][2]) + 
+    4.*f[1][0][1];
+  mm2 = f[0][2][0] + f[0][2][2] + f[2][2][0] + f[2][2][2] + 
+    2.*(f[0][2][1] + f[2][2][1] + f[1][2][0] + f[1][2][2]) + 
+    4.*f[1][2][1];
+  n->y = (mm1 - mm2)/32.;
+                  
+  mm1 = f[0][0][0] + f[0][2][0] + f[2][0][0] + f[2][2][0] +
+    2.*(f[0][1][0] + f[2][1][0] + f[1][0][0] + f[1][2][0]) + 
+    4.*f[1][1][0];
+  mm2 = f[0][0][2] + f[0][2][2] + f[2][0][2] + f[2][2][2] + 
+    2.*(f[0][1][2] + f[2][1][2] + f[1][0][2] + f[1][2][2]) + 
+    4.*f[1][1][2];
+  n->z = (mm1 - mm2)/32.;
+#endif /* 3D */
+}
+
+#if FTT_2D
+# include "myc2d.h"
+#else
+# include "myc.h"
+#endif
+
+static void myc_normal (FttCell * cell, GfsVariable * v, FttVector * n)
+{
+  gdouble F(3,3,3);  
+
+  stencil (cell, v, f);
+  mycs (f, &n->x);
+#if FTT_2D
+  n->z = 0.;
+#endif
+}
+
+static void vof_plane (FttCell * cell, GfsVariable * v)
+{
+  if (FTT_CELL_IS_LEAF (cell)) {
+    GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+    gdouble f = GFS_VALUE (cell, v);
+    FttComponent c;
+
+    THRESHOLD (f);
+    if (GFS_IS_FULL (f)) {
+      for (c = 1; c < FTT_DIMENSION; c++)
+	GFS_VALUE (cell, t->m[c]) = 0.;
+      GFS_VALUE (cell, t->m[0]) = 1.;
+      GFS_VALUE (cell, t->alpha) = f;
+    }
+    else {
+      FttVector m;
+      gdouble n = 0.;
+
+      myc_normal (cell, v, &m);
+      for (c = 0; c < FTT_DIMENSION; c++)
+	n += fabs ((&m.x)[c]);
+      if (n > 0.)
+	for (c = 0; c < FTT_DIMENSION; c++)
+	  (&m.x)[c] /= n;
+      else /* fixme: this is a small fragment */
+	m.x = 1.;
+      for (c = 0; c < FTT_DIMENSION; c++)
+	GFS_VALUE (cell, t->m[c]) = (&m.x)[c];
+      GFS_VALUE (cell, t->alpha) = gfs_plane_alpha (&m, f);
+    }
+  }
+}
+
+static void variable_tracer_vof_update (GfsVariable * v, GfsDomain * domain)
+{
+  GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+  guint l, depth = gfs_domain_depth (domain);
+  FttComponent c;
+  for (l = 0; l <= depth; l++) {
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEVEL, l,
+			      (FttCellTraverseFunc) vof_plane, v);
+    for (c = 0; c < FTT_DIMENSION; c++)
+      gfs_domain_bc (domain, FTT_TRAVERSE_LEVEL, l, t->m[c]);
+    gfs_domain_bc (domain, FTT_TRAVERSE_LEVEL, l, t->alpha);
+  }
+}
+
+static void no_coarse_fine (FttCell * cell,  GfsVariable * v) {}
+
+static void allocate_normal_alpha (GfsVariableTracerVOF * t)
+{
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    static gchar index[][2] = {"x", "y", "z"};
+    gchar * name = g_strdup_printf ("%s_%s", v->name, index[c]);
+    gchar * description = 
+      g_strdup_printf ("%s-component of the normal to the interface defined by %s",
+		       index[c], v->name);
+    t->m[c] = gfs_domain_get_or_add_variable (v->domain, name, description);
+    t->m[c]->fine_coarse = t->m[c]->coarse_fine = no_coarse_fine;
+    g_free (name);
+    g_free (description);
+  }
+  gchar * name = g_strdup_printf ("%s_alpha", v->name);
+  gchar * description = 
+    g_strdup_printf ("\"alpha\" for the interface defined by %s", v->name);
+  t->alpha = gfs_domain_get_or_add_variable (v->domain, name, description);
+  t->alpha->fine_coarse = t->alpha->coarse_fine = no_coarse_fine;
+  g_free (name);
+  g_free (description);
+}
+
+static gboolean variable_tracer_vof_event (GfsEvent * event, 
+					   GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_variable_tracer_vof_class ())->parent_class)->event)
+      (event, sim)) {
+    GfsVariable * v = GFS_VARIABLE1 (event);
+    GfsDomain * domain = GFS_DOMAIN (sim);
+    gfs_domain_cell_traverse (domain,
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_get_from_below_intensive, v);
+    gfs_domain_bc (GFS_DOMAIN (sim), FTT_TRAVERSE_ALL, -1, v);
+
+    GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+    if (!t->alpha)
+      allocate_normal_alpha (t);
+    variable_tracer_vof_update (v, domain);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void variable_tracer_vof_destroy (GtsObject * o)
+{
+  GfsVariableTracerVOF * v = GFS_VARIABLE_TRACER_VOF (o);
+
+  if (v->alpha) {
+    FttComponent c;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      gts_object_destroy (GTS_OBJECT (v->m[c]));
+    gts_object_destroy (GTS_OBJECT (v->alpha));
+  }
+
+  (* GTS_OBJECT_CLASS (gfs_variable_tracer_vof_class ())->parent_class->destroy) (o);
+}
+
+static void variable_tracer_vof_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_variable_tracer_vof_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  if (GFS_VARIABLE_TRACER (*o)->advection.cfl > 0.5) {
+    gts_file_error (fp, "cfl `%g' is out of range `]0,0.5]'", 
+		    GFS_VARIABLE_TRACER (*o)->advection.cfl);
+    return;
+  }  
+
+  allocate_normal_alpha (GFS_VARIABLE_TRACER_VOF (*o));
+}
+
+static void variable_tracer_vof_class_init (GtsObjectClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = variable_tracer_vof_event;
+  klass->destroy = variable_tracer_vof_destroy;
+  klass->read = variable_tracer_vof_read;
+}
+
+static void vof_coarse_fine (FttCell * parent, GfsVariable * v)
+{
+  GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+  gdouble f = GFS_VALUE (parent, v);
+  FttCellChildren child;
+  guint i;
+  
+  ftt_cell_children (parent, &child);
+  if (GFS_IS_FULL (f))
+    for (i = 0; i < FTT_CELLS; i++) {
+      FttComponent c;
+      if (!child.c[i])
+	g_assert_not_implemented ();
+      GFS_VALUE (child.c[i], v) = f;
+      for (c = 1; c < FTT_DIMENSION; c++)
+	GFS_VALUE (child.c[i], t->m[c]) = 0.;
+      GFS_VALUE (child.c[i], t->m[0]) = 1.;
+      GFS_VALUE (child.c[i], t->alpha) = f;
+    }
+  else {
+    gdouble alpha = GFS_VALUE (parent, t->alpha);
+    FttVector m;
+    
+    for (i = 0; i < FTT_DIMENSION; i++)
+      (&m.x)[i] = GFS_VALUE (parent, t->m[i]);
+    for (i = 0; i < FTT_CELLS; i++) {
+      gdouble alpha1 = alpha;
+      FttComponent c;
+      FttVector p;
+      
+      if (!child.c[i])
+	g_assert_not_implemented ();
+      ftt_cell_relative_pos (child.c[i], &p);
+      for (c = 0; c < FTT_DIMENSION; c++) {
+	alpha1 -= (&m.x)[c]*(0.25 + (&p.x)[c]);
+	GFS_VALUE (child.c[i], t->m[c]) = (&m.x)[c];
+      }
+      GFS_VALUE (child.c[i], v) = gfs_plane_volume (&m, 2.*alpha1);
+      GFS_VALUE (child.c[i], t->alpha) = 2.*alpha1;
+    }
+  }
+}
+
+static void vof_fine_coarse (FttCell * parent, GfsVariable * v)
+{
+  GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+  gfs_get_from_below_intensive (parent, v);
+  gdouble f = GFS_VALUE (parent, v);
+  FttComponent c;
+
+  if (GFS_IS_FULL (f)) {
+    for (c = 1; c < FTT_DIMENSION; c++)
+      GFS_VALUE (parent, t->m[c]) = 0.;
+    GFS_VALUE (parent, t->m[0]) = 1.;
+    GFS_VALUE (parent, t->alpha) = f;
+  }
+  else {
+    FttCellChildren child;
+    FttVector m = {0., 0., 0.};
+    guint i;
+    
+    ftt_cell_children (parent, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i]) {
+	gdouble f = GFS_VALUE (child.c[i], v);
+	gdouble a = f*(1. - f);
+
+	for (c = 0; c < FTT_DIMENSION; c++)
+	  (&m.x)[c] += a*GFS_VALUE (child.c[i], t->m[c]);
+      }
+    
+    gdouble n = 0.;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      n += fabs ((&m.x)[c]);
+    if (n > 0.)
+      for (c = 0; c < FTT_DIMENSION; c++)
+	(&m.x)[c] /= n;
+    else /* fixme: this is a small fragment */
+      m.x = 1.;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      GFS_VALUE (parent, t->m[c]) = (&m.x)[c];
+    GFS_VALUE (parent, t->alpha) = gfs_plane_alpha (&m, f);
+  }
+}
+
+static void variable_tracer_vof_init (GfsVariable * v)
+{
+  GFS_EVENT (v)->start = -1;
+  GFS_EVENT (v)->istep = G_MAXINT/2;
+  v->coarse_fine = vof_coarse_fine;
+  v->fine_coarse = vof_fine_coarse;
+  //  v->face_value = gfs_vof_face_value;
+  GFS_VARIABLE_TRACER (v)->advection.cfl = 0.5;
+}
+
+GfsVariableClass * gfs_variable_tracer_vof_class (void)
+{
+  static GfsVariableClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_variable_tracer_vof_info = {
+      "GfsVariableTracerVOF",
+      sizeof (GfsVariableTracerVOF),
+      sizeof (GfsVariableClass),
+      (GtsObjectClassInitFunc) variable_tracer_vof_class_init,
+      (GtsObjectInitFunc) variable_tracer_vof_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_variable_tracer_class ()), 
+				  &gfs_variable_tracer_vof_info);
+  }
+
+  return klass;
+}
+
+typedef struct {
+  GfsAdvectionParams * par, vpar;
+  FttComponent c;
+  GfsDomain * domain;
+  guint depth, too_coarse;
+} VofParms;
+
+static gdouble plane_volume_shifted (FttVector m, gdouble alpha, FttVector p[2])
+{
+  FttComponent c;
+
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    alpha -= (&m.x)[c]*(&p[0].x)[c];
+    (&m.x)[c] *= (&p[1].x)[c] - (&p[0].x)[c];
+  }
+  return gfs_plane_volume (&m, alpha);
+}
+
+static gdouble fine_fraction (FttCellFace * face, VofParms * p, gdouble un)
+{
+  gdouble f = GFS_VALUE (face->cell, p->par->v);
+  if (f == 0. || f == 1.)
+    return f;
+  else if (GFS_CELL_IS_BOUNDARY (face->cell))
+    return GFS_STATE (face->cell)->f[face->d].v;
+  else {
+    FttComponent c;
+    FttVector m;
+    gdouble alpha = GFS_VALUE (face->cell, GFS_VARIABLE_TRACER_VOF (p->par->v)->alpha);
+
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&m.x)[c] = GFS_VALUE (face->cell, GFS_VARIABLE_TRACER_VOF (p->par->v)->m[c]);
+    if (face->d % 2 != 0) {
+      (&m.x)[face->d/2] = - (&m.x)[face->d/2];
+      alpha += (&m.x)[face->d/2];
+    }
+
+    FttVector q[2] = {{0., 0., 0.},{1., 1., 1.}};
+
+    (&q[0].x)[face->d/2] = 1. - un; (&q[1].x)[face->d/2] = 1.;
+    return plane_volume_shifted (m, alpha, q);
+  }
+}
+
+static gdouble coarse_fraction (FttCellFace * face, VofParms * p, gdouble un)
+{
+  gdouble f = GFS_VALUE (face->neighbor, p->par->v);
+  if (f == 0. || f == 1.)
+    return f;
+  else {
+    FttVector q[2] = {{0., 0., 0.},{1., 1., 1.}};
+    FttComponent c;
+    FttVector m, o;
+    gdouble alpha = GFS_VALUE (face->neighbor, GFS_VARIABLE_TRACER_VOF (p->par->v)->alpha);
+    
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&m.x)[c] = GFS_VALUE (face->neighbor, GFS_VARIABLE_TRACER_VOF (p->par->v)->m[c]);
+    if (!FTT_FACE_DIRECT (face)) {
+      (&m.x)[face->d/2] = - (&m.x)[face->d/2];
+      alpha += (&m.x)[face->d/2];
+    }
+    
+    /* shift interface perpendicularly */
+    ftt_cell_relative_pos (face->cell, &o);
+    for (c = 0; c < FTT_DIMENSION; c++)
+      if (c != face->d/2) {
+	(&q[0].x)[c] = (&o.x)[c] + 0.25;
+	(&q[1].x)[c] = (&o.x)[c] + 0.75;
+      }
+    (&q[1].x)[face->d/2] = un;
+    return plane_volume_shifted (m, alpha, q);
+  }
+}
+
+#define TOO_COARSE(cell) (GFS_VALUE (cell, p->par->fv))
+
+/* Marks coarse cells which should be refined because an interface in
+   a neighboring finer cell will be advected into them */
+static void face_too_coarse (FttCellFace * face, VofParms * p)
+{
+  if (ftt_face_type (face) == FTT_FINE_COARSE) {
+    gdouble un = GFS_FACE_NORMAL_VELOCITY (face);
+    if (!FTT_FACE_DIRECT (face))
+      un = - un;
+    if (un > 0.) {
+      gdouble f = GFS_VALUE (face->neighbor, p->par->v);
+      if (GFS_IS_FULL (f) &&
+	  fine_fraction (face, p, un*p->par->dt/ftt_cell_size (face->cell)) != f) {
+	p->too_coarse++;
+	TOO_COARSE (face->neighbor) = TRUE;
+      }
+    }
+  }
+}
+
+static void vof_cell_fine_init (FttCell * parent, VofParms * p)
+{
+  gfs_cell_fine_init (parent, p->domain);
+
+  FttDirection d;
+  for (d = 0; d < FTT_NEIGHBORS; d++) {
+    FttDirection od = FTT_OPPOSITE_DIRECTION (d);
+    FttCellChildren dchild;
+    guint i, n = ftt_cell_children_direction (parent, d, &dchild);
+    for (i = 0; i < n; i++) {
+      g_assert (dchild.c[i]);
+      FttCell * neighbor = ftt_cell_neighbor (dchild.c[i], d);
+      if (neighbor)
+	GFS_STATE (dchild.c[i])->f[d].un = GFS_STATE (neighbor)->f[od].un;
+    }
+  }
+
+  FttCellChildren child;
+  gdouble div[FTT_CELLS], P[FTT_CELLS];
+  guint n;
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++) {
+    g_assert (child.c[n]);
+    GFS_VALUE (child.c[n], p->vpar.v) = GFS_VALUE (parent, p->vpar.v);
+    div[n] = 0.;
+    FttComponent c;
+    for (c = 0; c < FTT_DIMENSION; c++)
+      div[n] += GFS_STATE (child.c[n])->f[2*c].un - GFS_STATE (child.c[n])->f[2*c + 1].un;
+  }
+
+#if FTT_2D
+  P[0] = 0.;
+  P[1] = (3.*div[1] + div[2])/4. + div[3]/2.;
+  P[2] = (div[1] + 3.*div[2])/4. + div[3]/2.;
+  P[3] = (div[1] + div[2])/2. + div[3];
+  GFS_STATE (child.c[0])->f[0].un = GFS_STATE (child.c[1])->f[1].un = P[1] - P[0];
+  GFS_STATE (child.c[2])->f[0].un = GFS_STATE (child.c[3])->f[1].un = P[3] - P[2];
+  GFS_STATE (child.c[0])->f[3].un = GFS_STATE (child.c[2])->f[2].un = P[0] - P[2];
+  GFS_STATE (child.c[1])->f[3].un = GFS_STATE (child.c[3])->f[2].un = P[1] - P[3];
+#else /* 3D */
+  static gdouble m[7][7] = {{7./12.,5./24.,3./8.,5./24.,3./8.,1./4.,1./3.},
+			    {5./24.,7./12.,3./8.,5./24.,1./4.,3./8.,1./3.}, 
+			    {3./8.,3./8.,3./4.,1./4.,3./8.,3./8.,1./2.}, 
+			    {5./24.,5./24.,1./4.,7./12.,3./8.,3./8.,1./3.}, 
+			    {3./8.,1./4.,3./8.,3./8.,3./4.,3./8.,1./2.}, 
+			    {1./4.,3./8.,3./8.,3./8.,3./8.,3./4.,1./2.}, 
+			    {1./3.,1./3.,1./2.,1./3.,1./2.,1./2.,5./6.}};
+  P[0] = 0.;
+  guint i, j;
+  for (i = 0; i < 7; i++) {
+    P[i + 1] = 0.;
+    for (j = 0; j < 7; j++)
+      P[i + 1] += m[i][j]*div[j + 1];
+  }
+  GFS_STATE (child.c[0])->f[0].un = GFS_STATE (child.c[1])->f[1].un = P[1] - P[0];
+  GFS_STATE (child.c[2])->f[0].un = GFS_STATE (child.c[3])->f[1].un = P[3] - P[2];
+  GFS_STATE (child.c[0])->f[3].un = GFS_STATE (child.c[2])->f[2].un = P[0] - P[2];
+  GFS_STATE (child.c[1])->f[3].un = GFS_STATE (child.c[3])->f[2].un = P[1] - P[3];
+
+  GFS_STATE (child.c[4])->f[0].un = GFS_STATE (child.c[5])->f[1].un = P[5] - P[4];
+  GFS_STATE (child.c[6])->f[0].un = GFS_STATE (child.c[7])->f[1].un = P[7] - P[6];
+  GFS_STATE (child.c[4])->f[3].un = GFS_STATE (child.c[6])->f[2].un = P[4] - P[6];
+  GFS_STATE (child.c[5])->f[3].un = GFS_STATE (child.c[7])->f[2].un = P[5] - P[7];
+
+  GFS_STATE (child.c[0])->f[5].un = GFS_STATE (child.c[4])->f[4].un = P[0] - P[4];
+  GFS_STATE (child.c[1])->f[5].un = GFS_STATE (child.c[5])->f[4].un = P[1] - P[5];
+  GFS_STATE (child.c[2])->f[5].un = GFS_STATE (child.c[6])->f[4].un = P[2] - P[6];
+  GFS_STATE (child.c[3])->f[5].un = GFS_STATE (child.c[7])->f[4].un = P[3] - P[7];
+#endif /* 3D */
+}
+
+/* Same as vof_cell_fine_init() but initialisation of MAC velocities
+   is done through a GfsVariableStreamFunction */
+static void vof_cell_fine_init_with_streamfunction (FttCell * parent, VofParms * p)
+{
+  gfs_cell_fine_init (parent, p->domain);
+
+  FttCellChildren child;
+  guint n;
+  ftt_cell_children (parent, &child);
+  for (n = 0; n < FTT_CELLS; n++) {
+    g_assert (child.c[n]);
+    GFS_VALUE (child.c[n], p->vpar.v) = GFS_VALUE (parent, p->vpar.v);
+  }
+}
+
+static void refine_too_coarse (FttCell * cell, VofParms * p)
+{
+  if (TOO_COARSE (cell)) {
+    guint level = ftt_cell_level (cell);
+
+    TOO_COARSE (cell) = FALSE;
+    ftt_cell_refine_corners (cell, (FttCellInitFunc) p->domain->cell_init, p);
+    ftt_cell_refine_single (cell, (FttCellInitFunc) p->domain->cell_init, p);
+    if (level + 1 > p->depth)
+      p->depth = level + 1;
+  }
+}
+
+static void vof_face_value (FttCellFace * face, VofParms * p)
+{
+  gdouble un = GFS_FACE_NORMAL_VELOCITY (face)*p->par->dt/ftt_cell_size (face->cell);
+  if (!FTT_FACE_DIRECT (face))
+    un = - un;
+
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE: {
+    if (un < 0.) {
+      FttCell * tmp = face->cell;
+      face->cell = face->neighbor;
+      face->neighbor = tmp;
+      face->d = FTT_OPPOSITE_DIRECTION (face->d);
+      un = - un;
+    }
+    GFS_STATE (face->cell)->f[face->d].v = fine_fraction (face, p, un);
+    break;
+  }
+  case FTT_FINE_COARSE: {
+    GFS_STATE (face->cell)->f[face->d].v = 
+      un > 0. ? fine_fraction (face, p, un) : coarse_fraction (face, p, -un/2.);
+    break;
+  }
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+static void vof_flux (FttCellFace * face, VofParms * p)
+{
+  gdouble un = GFS_FACE_NORMAL_VELOCITY (face)*p->par->dt/ftt_cell_size (face->cell);
+  if (!FTT_FACE_DIRECT (face))
+    un = - un;
+  if (fabs (un) > 0.5) {
+    FttVector p;
+    ftt_face_pos (face, &p);
+    g_warning ("CFL (%g) at (%g,%g,%g) is larger than 0.5!", un, p.x, p.y, p.z);
+  }
+  un *= gfs_domain_face_fraction (p->par->fv->domain, face);
+
+  gdouble flux = GFS_STATE (face->cell)->f[face->d].v*un;
+  switch (ftt_face_type (face)) {
+  case FTT_FINE_FINE: {
+    if (un < 0.)
+      flux = GFS_STATE (face->neighbor)->f[FTT_OPPOSITE_DIRECTION (face->d)].v*un;
+    GFS_VALUE (face->neighbor, p->par->fv) += flux;
+    GFS_VALUE (face->neighbor, p->vpar.fv) += un;
+    break;
+  }
+  case FTT_FINE_COARSE: {
+    GFS_VALUE (face->neighbor, p->par->fv) += flux/FTT_CELLS;
+    GFS_VALUE (face->neighbor, p->vpar.fv) += un/FTT_CELLS;
+    break;
+  }
+  default:
+    g_assert_not_reached ();
+  }
+  GFS_VALUE (face->cell, p->par->fv) -= flux;
+  GFS_VALUE (face->cell, p->vpar.fv) -= un;
+}
+
+static void initialize_dV (FttCell * cell, GfsVariable * dV)
+{
+  GFS_VALUE (cell, dV) = 1.;
+}
+
+static void f_times_dV (FttCell * cell, VofParms * p)
+{
+  GFS_VALUE (cell, p->par->fv) = 0.;
+  GFS_VALUE (cell, p->vpar.fv) = 0.;
+  GFS_VALUE (cell, p->par->v) *= GFS_VALUE (cell, p->vpar.v);
+}
+
+static void f_over_dV (FttCell * cell, VofParms * p)
+{
+  g_assert (GFS_VALUE (cell, p->vpar.v) > 0.);
+  gdouble f = GFS_VALUE (cell, p->par->v)/GFS_VALUE (cell, p->vpar.v);
+  GFS_VALUE (cell, p->par->v) = f < 1e-10 ? 0. : f > 1. - 1e-10 ? 1. : f;
+}
+
+/* refine cells which would lead to a loss of resolution at the interface */
+static void fix_too_coarse (GfsDomain * domain, VofParms * p)
+{
+  p->depth = 0;
+  p->domain = domain;
+  p->too_coarse = 0;
+  gfs_domain_face_traverse (domain, p->c,
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttFaceTraverseFunc) face_too_coarse, p);
+  gboolean streamfunction = FALSE;
+#if FTT_2D
+  GSList * i = domain->variables;
+  while (i && !streamfunction) {
+    streamfunction = (GFS_IS_VARIABLE_STREAM_FUNCTION (i->data) != NULL);
+    i = i->next;
+  }
+#endif /* 2D */ 
+  domain->cell_init = (FttCellInitFunc) (streamfunction ? 
+					 vof_cell_fine_init_with_streamfunction : 
+					 vof_cell_fine_init);
+  domain->cell_init_data = p;
+  if (p->too_coarse > 0)
+    gfs_domain_cell_traverse (domain,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) refine_too_coarse, p);
+  gfs_all_reduce (domain, p->too_coarse, MPI_UNSIGNED, MPI_SUM);
+  if (p->too_coarse > 0)
+    gfs_domain_reshape (domain, p->depth);
+  domain->cell_init = (FttCellInitFunc) gfs_cell_fine_init;
+  domain->cell_init_data = domain;
+}
+
+/**
+ * gfs_tracer_vof_advection:
+ * @domain: a #GfsDomain.
+ * @par: the advection parameters.
+ *
+ * Advects the @v field of @par using the current face-centered (MAC)
+ * velocity field.
+ */
+void gfs_tracer_vof_advection (GfsDomain * domain,
+			       GfsAdvectionParams * par)
+{
+  VofParms p;
+  static FttComponent cstart = 0;
+  FttComponent c;
+
+  g_return_if_fail (domain != NULL);
+  g_return_if_fail (par != NULL);
+  g_return_if_fail (GFS_IS_VARIABLE_TRACER_VOF (par->v));
+  g_return_if_fail (par->cfl <= 0.5);
+
+  gfs_domain_timer_start (domain, "tracer_vof_advection");
+
+  p.par = par;
+  gfs_advection_params_init (&p.vpar);
+  p.vpar.v = gfs_temporary_variable (domain);
+  p.vpar.fv = gfs_temporary_variable (domain);
+  p.vpar.average = par->average;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) initialize_dV, p.vpar.v);
+  par->fv = gfs_temporary_variable (domain);
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    p.c = (cstart + c) % FTT_DIMENSION;
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_cell_reset, par->fv);
+    fix_too_coarse (domain, &p);
+    gfs_domain_face_traverse (domain, p.c,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) vof_face_value, &p);
+    gfs_domain_face_bc (domain, p.c, par->v);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) f_times_dV, &p);
+    gfs_domain_face_traverse (domain, p.c,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) vof_flux, &p);
+    gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, par);
+    gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, &p.vpar);
+    gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+    			      (FttCellTraverseFunc) f_over_dV, &p);
+    gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) par->v->fine_coarse, par->v);
+    gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, par->v);
+
+    variable_tracer_vof_update (p.par->v, domain);
+  }
+  cstart = (cstart + 1) % FTT_DIMENSION;
+  gts_object_destroy (GTS_OBJECT (par->fv));
+  par->fv = NULL;
+  gts_object_destroy (GTS_OBJECT (p.vpar.v));
+  gts_object_destroy (GTS_OBJECT (p.vpar.fv));
+
+  gfs_domain_timer_stop (domain, "tracer_vof_advection");
+}
+
+static gdouble face_value (FttCell * cell, FttDirection d, GfsVariable * v)
+{
+  gdouble f = GFS_VALUE (cell, v);
+
+  if (GFS_IS_FULL (f))
+    return f;
+  else {
+    GfsVariableTracerVOF * t = GFS_VARIABLE_TRACER_VOF (v);
+    gdouble alpha = GFS_VALUE (cell, t->alpha);
+    FttComponent c;
+    FttVector m;
+    
+    for (c = 0; c < FTT_DIMENSION; c++)
+      (&m.x)[c] = GFS_VALUE (cell, t->m[c]);
+    (&m.x)[d/2] /= 2.;
+    if (d % 2)
+      alpha -= (&m.x)[d/2];
+    return gfs_plane_volume (&m, alpha);
+  }
+}
+
+/**
+ * gfs_vof_face_value:
+ * @face: a #FttCellFace.
+ * @t: a #GfsVariableTracerVOF.
+ *
+ * Returns: the value of the VOF fraction defined by @t, interpolated
+ * on @face.
+ */
+gdouble gfs_vof_face_value (const FttCellFace * face, GfsVariableTracerVOF * t)
+{
+  g_return_val_if_fail (face != NULL, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  gdouble vright, vleft = GFS_VALUE (face->cell, v); //face_value (face->cell, face->d, v);
+  if (ftt_face_type (face) == FTT_FINE_COARSE) {
+    gdouble f = GFS_VALUE (face->neighbor, v);
+
+    if (GFS_IS_FULL (f))
+      vright = f;
+    else {
+      gdouble alpha = GFS_VALUE (face->neighbor, t->alpha);
+      FttComponent c;
+      FttVector m;
+
+      for (c = 0; c < FTT_DIMENSION; c++)
+	(&m.x)[c] = GFS_VALUE (face->neighbor, t->m[c]);
+
+      FttVector p, o;
+      ftt_face_pos (face, &p);
+      ftt_cell_pos (face->neighbor, &o);
+      gdouble h = ftt_cell_size (face->neighbor);
+
+      (&p.x)[face->d/2] += face->d % 2 ? -h/4. : h/4.;
+      for (c = 0; c < FTT_DIMENSION; c++)
+	alpha -= (&m.x)[c]*(0.25 - ((&p.x)[c] - (&o.x)[c])/h);
+      //      for (c = 0; c < FTT_DIMENSION; c++)
+      //	(&m.x)[c] /= 2.;
+      //      (&m.x)[face->d/2] /= 2.;
+      //      if (!(face->d % 2))
+      //	alpha -= (&m.x)[face->d/2];
+      vright = gfs_plane_volume (&m, 2.*alpha);
+#if 0
+      if (vright > 0.2 && vright < 0.8) {
+	fprintf (stderr, "%d (%g,%g) (%g,%g) %g\n", face->d, p.x, p.y, o.x, o.y, vright);
+	g_assert_not_reached ();
+      }
+#endif
+    }
+  }
+  else
+    vright = GFS_VALUE (face->neighbor, v); //face_value (face->neighbor, FTT_OPPOSITE_DIRECTION (face->d), v);
+  return (vright + vleft)/2.;
+}
+
+/**
+ * gfs_vof_facet:
+ * @cell: a #FttCell.
+ * @t: a #GfsVariableTracerVOF.
+ * @p: a #FttVector array (of size 2 in 2D and 6 in 3D)
+ * @m: a #FttVector.
+ *
+ * Fills @p with the coordinates of points defining the
+ * VOF-reconstructed interface facet defined by @t.
+ *
+ * Fills @m with the normal to the interface.
+ *
+ * Returns: the number of points defining the facet.
+ */
+guint gfs_vof_facet (FttCell * cell,
+		     GfsVariableTracerVOF * t,
+		     FttVector * p,
+		     FttVector * m)
+{
+  g_return_val_if_fail (cell != NULL, 0);
+  g_return_val_if_fail (t != NULL, 0);
+  g_return_val_if_fail (p != NULL, 0);
+  g_return_val_if_fail (m != NULL, 0);
+
+  if (GFS_IS_FULL (GFS_VALUE (cell, GFS_VARIABLE1 (t))))
+    return 0;
+
+  guint n = 0;
+  FttVector q;
+  ftt_cell_pos (cell, &q);
+  gdouble h = ftt_cell_size (cell);
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m->x)[c] = GFS_VALUE (cell, t->m[c]);
+  gdouble alpha = GFS_VALUE (cell, t->alpha);
+
+#if FTT_2D
+  gdouble x, y;
+
+  if (fabs (m->y) > EPS) {
+    y = (alpha - m->x)/m->y;
+    if (y >= 0. && y <= 1.) {
+      p[n].x = q.x + h/2.; p[n].y = q.y + h*(y - 0.5); p[n++].z = 0.;
+    }
+  }
+  if (fabs (m->x) > EPS) {
+    x = (alpha - m->y)/m->x;
+    if (x >= 0. && x <= 1.) {
+      p[n].x = q.x + h*(x - 0.5); p[n].y = q.y + h/2.; p[n++].z = 0.;
+    }
+  }
+  if (fabs (m->y) > EPS) {
+    y = alpha/m->y;
+    if (y >= 0. && y <= 1.) {
+      p[n].x = q.x - h/2.; p[n].y = q.y + h*(y - 0.5); p[n++].z = 0.;
+    }
+  }
+  if (fabs (m->x) > EPS) {
+    x = alpha/m->x;
+    if (x >= 0. && x <= 1.) {
+      p[n].x = q.x + h*(x - 0.5); p[n].y = q.y - h/2.; p[n++].z = 0.;
+    }
+  }
+  g_assert (n <= 2);
+#else /* 3D */
+  gdouble max = fabs (m->x);
+  c = FTT_X;
+  if (fabs (m->y) > max) {
+    max = fabs (m->y);
+    c = FTT_Y;
+  }
+  if (fabs (m->z) > max)
+    c = FTT_Z;
+  q.x -= h/2.; q.y -= h/2.; q.z -= h/2.;
+  (&q.x)[c] += h*alpha/(&m->x)[c];
+  FttVector m1 = *m;
+  gts_vector_normalize (&m1.x);
+
+  FttDirection d[12];
+  n = gfs_cut_cube_vertices (cell, -1, &q, &m1, p, d, NULL, NULL);
+  g_assert (n <= 6);
+#endif /* 3D */
+  return n;
+}
+
+/**
+ * gfs_vof_facet_distance2:
+ * @cell: a #FttCell.
+ * @t: a #GfsVariableTracerVOF.
+ * @p: a #GtsPoint.
+ *
+ * Returns: the square of the distance between point @p and the
+ * VOF-reconstructed interface facet defined by @t or %G_MAXDOUBLE if
+ * @cell does not contain an interface.
+ */
+gdouble gfs_vof_facet_distance2 (FttCell * cell,
+				 GfsVariableTracerVOF * t,
+				 GtsPoint * p)
+{
+  g_return_val_if_fail (cell != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (t != NULL, G_MAXDOUBLE);
+  g_return_val_if_fail (p != NULL, G_MAXDOUBLE);
+
+  if (GFS_IS_FULL (GFS_VALUE (cell, GFS_VARIABLE1 (t))))
+    return G_MAXDOUBLE;
+
+  FttVector q, m;
+  ftt_cell_pos (cell, &q);
+  gdouble h = ftt_cell_size (cell), lambda = 0., norm2 = 0.;
+  FttComponent c;
+  q.x -= h/2.; q.y -= h/2.; q.z -= h/2.;
+  /* compute position of closest point on VOF plane m*x + m*y + m*z = alpha */
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    (&m.x)[c] = GFS_VALUE (cell, t->m[c]);
+    lambda += (&m.x)[c]*((&p->x)[c] - (&q.x)[c])/h;
+    norm2 += (&m.x)[c]*(&m.x)[c];
+  }
+  gdouble alpha = GFS_VALUE (cell, t->alpha);
+  g_assert (norm2 > 0.);
+  lambda = (lambda - alpha)/norm2;
+
+  FttVector o;
+  for (c = 0; c < FTT_DIMENSION; c++) {
+    (&o.x)[c] = ((&p->x)[c] - (&q.x)[c])/h - lambda*(&m.x)[c];
+    if ((&o.x)[c] <= 0. || (&o.x)[c] >= 1.) {
+      /* closest point on VOF plane is not within cell
+	 return minimum distance from facet edges */
+      FttVector q[FTT_DIMENSION*(FTT_DIMENSION - 1) + 1];
+      gdouble dmin = G_MAXDOUBLE;
+      guint i, n = gfs_vof_facet (cell, t, q, &m);
+#if !FTT_2D
+      if (n > 2)
+	q[n++] = q[0];
+#endif
+      for (i = 0; i < n - 1; i++) {
+	GtsPoint p1, p2;
+	p1.x = q[i].x; p1.y = q[i].y; p1.z = q[i].z;
+	p2.x = q[i + 1].x; p2.y = q[i + 1].y; p2.z = q[i + 1].z;
+	GtsSegment s;
+	s.v1 = (GtsVertex *) &p1; s.v2 = (GtsVertex *) &p2;
+	gdouble d = gts_point_segment_distance2 (p, &s);
+	if (d < dmin)
+	  dmin = d;
+      }
+      return dmin;
+    }
+  }
+  return h*h*lambda*lambda*norm2;
+}
+
+/**
+ * gfs_vof_center:
+ * @cell: a #FttCell.
+ * @t: a #GfsVariableTracerVOF.
+ * @p: a #FttVector.
+ *
+ * Fills @p with the coordinates of the center of mass of the
+ * VOF-reconstructed interface facet defined by @t.
+ *
+ * Returns: the area (length in 2D) of the VOF-reconstructed facet or 0. if the
+ * cell is not cut by the interface.
+ */
+gdouble gfs_vof_center (FttCell * cell, GfsVariableTracerVOF * t, FttVector * p)
+{
+  g_return_val_if_fail (cell != NULL, FALSE);
+  g_return_val_if_fail (t != NULL, FALSE);
+  g_return_val_if_fail (p != NULL, 0);
+
+  if (GFS_IS_FULL (GFS_VALUE (cell, GFS_VARIABLE1 (t))))
+    return 0.;
+
+  FttVector m, o;
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m.x)[c] = GFS_VALUE (cell, t->m[c]);
+  gdouble area = gfs_plane_area_center (&m, GFS_VALUE (cell, t->alpha), p);
+  ftt_cell_pos (cell, &o);
+  gdouble h = ftt_cell_size (cell);
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&p->x)[c] = (&o.x)[c] + h*((&p->x)[c] - 0.5);
+  return area;
+}
+
+static gdouble fraction (FttVector * p,
+			 guint level,
+			 GfsVariable * v)
+{
+  FttCell * cell = gfs_domain_boundary_locate (v->domain, *p, level, NULL);
+  if (cell)
+    return gfs_vof_interpolate (cell, p, level, GFS_VARIABLE_TRACER_VOF (v));
+  else /* fixme: boundary conditions? */
+    return 2.;
+}
+
+#define NMAX 10
+
+#define ADD_H(f) { H += f; n++; }
+#define SIGN(x) ((x) > 0. ? 1. : -1.)
+
+static gdouble local_height (FttVector * p,
+			     FttVector * origin,
+			     guint level,
+			     GfsVariable * v,
+			     FttDirection d,
+			     GtsVector interface)
+{
+  gdouble h = ftt_level_size (level), h1 = d % 2 ? - h : h, H = 0.;
+  gdouble right = fraction (p, level, v), left = right;
+  FttVector pright = *p, pleft = pright;
+  FttComponent c = d/2;
+  guint n = 0;
+
+  ADD_H (right);
+  gboolean found_interface = (right > 0.);
+  while (n < NMAX && (!found_interface || !GFS_IS_FULL (right))) {
+    (&pright.x)[c] += h1;
+    right = fraction (&pright, level, v);
+    if (right > 1.)
+      return G_MAXDOUBLE;
+    ADD_H (right);
+    if (!GFS_IS_FULL (right))
+      found_interface = TRUE;
+  }
+  if (right != 1.)
+    return G_MAXDOUBLE;
+
+  found_interface = (left < 1.);
+  while (n < NMAX && (!found_interface || !GFS_IS_FULL (left))) {
+    (&pleft.x)[c] -= h1;
+    left = fraction (&pleft, level, v);
+    if (left > 1.)
+      return G_MAXDOUBLE;
+    ADD_H (left);
+    if (!GFS_IS_FULL (left))
+      found_interface = TRUE;
+  }
+  if (left != 0.)
+    return G_MAXDOUBLE;
+
+  H -= ((&pright.x)[c] - (&origin->x)[c])/h1 + 0.5;
+  interface[0] = (p->x - origin->x)/h;
+  interface[1] = (p->y - origin->y)/h;
+  interface[2] = (p->z - origin->z)/h;
+  interface[c] = - SIGN (h1)*H;
+  return H;
+}
+
+/* fixme: does not work for periodic boundary conditions along direction c
+ * for cells close to the boundary */
+static gboolean curvature_along_direction (FttCell * cell, 
+					   GfsVariableTracerVOF * t,
+					   FttComponent c,
+					   gdouble * kappa,
+					   gdouble * kmax,
+					   GtsVector * interface,
+					   guint * n)
+{
+  GfsVariable * v = GFS_VARIABLE1 (t);
+
+  FttVector m;
+  FttComponent i;
+  for (i = 0; i < FTT_DIMENSION; i++)
+    (&m.x)[i] = GFS_VALUE (cell, t->m[i]);
+  FttDirection d = 2*c + ((&m.x)[c] > 0.);
+
+  FttVector p;
+  ftt_cell_pos (cell, &p);
+  guint level = ftt_cell_level (cell);
+  gdouble size = ftt_level_size (level), H;
+
+  gboolean found_all_heights = TRUE;
+  H = local_height (&p, &p, level, v, d, interface[*n]);
+  if (H == G_MAXDOUBLE)
+    found_all_heights = FALSE;
+  else
+    (*n)++;
+#if 0
+  if (H < -0.5 || H > 0.5)
+    found_all_heights = FALSE;
+#endif
+
+#ifdef FTT_2D
+  FttComponent cp = FTT_ORTHOGONAL_COMPONENT (c);
+  FttVector q = p;
+  gdouble h[2];
+  (&q.x)[cp] += size;
+  h[0] = local_height (&q, &p, level, v, d, interface[*n]);
+  if (h[0] == G_MAXDOUBLE)
+    found_all_heights = FALSE;
+  else
+    (*n)++;
+
+  q = p;
+  (&q.x)[cp] -= size;
+  h[1] = local_height (&q, &p, level, v, d, interface[*n]);
+  if (h[1] == G_MAXDOUBLE)
+    found_all_heights = FALSE;
+  else
+    (*n)++;
+
+  if (found_all_heights) {
+    gdouble hxx = h[0] - 2.*H + h[1];
+    gdouble hx = (h[0] - h[1])/2.;
+    gdouble dnm = 1. + hx*hx;
+    *kappa = hxx/(size*sqrt (dnm*dnm*dnm));
+    if (kmax)
+      *kmax = fabs (*kappa);
+    if (GFS_IS_AXI (v->domain)) {
+      gdouble nr, r = p.y;
+      if (c == FTT_X)
+	nr = hx;
+      else {
+	r += (d == FTT_TOP ? - H*size : H*size);
+	nr = (d == FTT_TOP ? 1. : -1.);
+      }
+      gdouble kaxi = nr/(sqrt(dnm)*r);
+      *kappa += kaxi;
+      if (kmax)
+	*kmax = MAX (*kmax, fabs (kaxi));
+    }
+  }
+#else  /* 3D */  
+  static FttComponent or[3][2] = { { FTT_Y, FTT_Z }, { FTT_X, FTT_Z }, { FTT_X, FTT_Y } };
+  gdouble h[3][3];
+  gint x, y;
+
+  for (x = -1; x <= 1; x++)
+    for (y = -1; y <= 1; y++)
+      if (x != 0 || y != 0) {
+	FttVector q = p;
+	(&q.x)[or[c][0]] += size*x;
+	(&q.x)[or[c][1]] += size*y;
+	h[x + 1][y + 1] = local_height (&q, &p, level, v, d, interface[*n]);
+	if (h[x + 1][y + 1] == G_MAXDOUBLE)
+	  found_all_heights = FALSE;
+	else
+	  (*n)++;
+      }
+
+  if (found_all_heights) {
+    gdouble hxx = h[2][1] - 2.*H + h[0][1];
+    gdouble hyy = h[1][2] - 2.*H + h[1][0];
+    gdouble hx = (h[2][1] - h[0][1])/2.;
+    gdouble hy = (h[1][2] - h[1][0])/2.;
+    gdouble hxy = (h[2][2] + h[0][0] - h[2][0] - h[0][2])/4.;
+    gdouble dnm = 1. + hx*hx + hy*hy; 
+    *kappa = (hxx + hyy + hxx*hy*hy + hyy*hx*hx - 2.*hxy*hx*hy)/(size*sqrt (dnm*dnm*dnm));  
+    if (kmax) {
+      gdouble km = *kappa/2.;
+      /* Gaussian curvature */
+      gdouble kg = (hxx*hyy - hxy*hxy)/(size*size*dnm*dnm);
+      gdouble a = km*km - kg;
+      *kmax = fabs (km);
+      if (a >= 0.)
+	*kmax += sqrt (a);
+    }
+  }
+#endif /* 3D */
+  return found_all_heights;
+}
+
+#define PARABOLA_FIT_CENTER_WEIGHT .1
+#define PARABOLA_SIMPLER 0
+
+typedef struct {
+  GtsVector o;
+#if FTT_2D /* y = a[0]*x^2 + a[0]*x + a[1] */
+  GtsVector m;
+  GtsMatrix * M;
+  GtsVector rhs, a;
+#else /* 3D */
+# if PARABOLA_SIMPLER /* z = a[0]*x^2 + a[1]*y^2 + a[2]*x*y */
+  GtsMatrix * M;
+  GtsVector rhs, a;
+# else /* z = a[0]*x^2 + a[1]*y^2 + a[2]*x*y + a[3]*x + a[4]*y + a[5] */
+  gdouble ** M, rhs[6], a[6];
+# endif
+  GtsVector t[3];
+#endif /* 3D */
+} ParabolaFit;
+
+static void parabola_fit_init (ParabolaFit * p, FttVector * o, FttVector * m)
+{
+  p->o[0] = o->x; p->o[1] = o->y; p->o[2] = o->z;
+#if FTT_2D
+  p->m[0] = m->x; p->m[1] = m->y; p->m[2] = 0.;
+  gts_vector_normalize (p->m);
+  p->M = gts_matrix_zero (NULL);
+  p->rhs[0] = p->rhs[1] = p->rhs[2] = 0.;
+#else /* 3D */
+  gdouble max;
+  GtsVector nx = {0., 0., 0.}, ny, nz;
+  guint d = 0;
+
+  nz[0] = m->x; nz[1] = m->y; nz[2] = m->z;
+  gts_vector_normalize (nz);
+  max = nz[0]*nz[0];
+  /* build a vector orthogonal to nz */
+  if (nz[1]*nz[1] > max) { max = nz[1]*nz[1]; d = 1; }
+  if (nz[2]*nz[2] > max) d = 2;
+  switch (d) {
+  case 0: nx[0] = - nz[2]/nz[0]; nx[2] = 1.0; break;
+  case 1: nx[1] = - nz[2]/nz[1]; nx[2] = 1.0; break;
+  case 2: nx[2] = - nz[0]/nz[2]; nx[0] = 1.0; break;
+  }
+  gts_vector_normalize (nx);
+
+  /* build a second vector orthogonal to nx and nz */
+  gts_vector_cross (ny, nz, nx);
+
+  /* transformation matrix from (i,j,k) to (nx, ny, nz) */
+  p->t[0][0] = nx[0]; p->t[0][1] = nx[1]; p->t[0][2] = nx[2];
+  p->t[1][0] = ny[0]; p->t[1][1] = ny[1]; p->t[1][2] = ny[2];
+  p->t[2][0] = nz[0]; p->t[2][1] = nz[1]; p->t[2][2] = nz[2];
+
+# if PARABOLA_SIMPLER
+  p->M = gts_matrix_zero (NULL);
+  p->rhs[0] = p->rhs[1] = p->rhs[2] = 0.;
+# else
+  p->M = gfs_matrix_new (6, 6, sizeof (gdouble));
+  p->rhs[0] = p->rhs[1] = p->rhs[2] = p->rhs[3] = p->rhs[4] = p->rhs[5] = 0.;
+# endif
+#endif /* 3D */
+}
+
+static void parabola_fit_add (ParabolaFit * p, GtsVector m, gdouble w)
+{
+#if FTT_2D
+  gdouble x1 = m[0] - p->o[0];
+  gdouble y1 = m[1] - p->o[1];
+  gdouble x = p->m[1]*x1 - p->m[0]*y1;
+  gdouble y = p->m[0]*x1 + p->m[1]*y1;
+  gdouble x2 = w*x*x, x3 = x2*x, x4 = x3*x;
+  p->M[0][0] += x4;
+  p->M[1][0] += x3; p->M[1][1] += x2;
+  p->M[2][1] += w*x; p->M[2][2] += w;
+  p->rhs[0] += x2*y;
+  p->rhs[1] += w*x*y;
+  p->rhs[2] += w*y;
+#else /* 3D */
+  gdouble x1 = m[0] - p->o[0];
+  gdouble y1 = m[1] - p->o[1];
+  gdouble z1 = m[2] - p->o[2];
+  gdouble x = p->t[0][0]*x1 + p->t[0][1]*y1 + p->t[0][2]*z1;
+  gdouble y = p->t[1][0]*x1 + p->t[1][1]*y1 + p->t[1][2]*z1;
+  gdouble z = p->t[2][0]*x1 + p->t[2][1]*y1 + p->t[2][2]*z1;
+  gdouble x2 = x*x, x3 = x2*x, x4 = x3*x;
+  gdouble y2 = y*y, y3 = y2*y, y4 = y3*y;
+# if PARABOLA_SIMPLER
+  p->M[0][0] += w*x4;
+  p->M[1][0] += w*x2*y2; p->M[1][1] += w*y4;
+  p->M[2][0] += w*x3*y;  p->M[2][1] += w*x*y3;
+  p->rhs[0] += w*z*x2;   p->rhs[1] += w*z*y2;  p->rhs[2] += w*z*x*y;
+# else
+  p->M[0][0] += w*x4; p->M[1][1] += w*y4; p->M[2][2] += w*x2*y2; 
+  p->M[3][3] += w*x2; p->M[4][4] += w*y2; p->M[5][5] += w;
+  p->M[0][2] += w*x3*y; p->M[0][3] += w*x3; p->M[0][4] += w*x2*y;
+  p->M[1][2] += w*x*y3; p->M[1][3] += w*x*y2; p->M[1][4] += w*y3;
+  p->M[2][5] += w*x*y;
+  p->M[3][5] += w*x;
+  p->M[4][5] += w*y;
+  p->rhs[0] += w*x2*z; p->rhs[1] += w*y2*z; p->rhs[2] += w*x*y*z;
+  p->rhs[3] += w*x*z; p->rhs[4] += w*y*z; p->rhs[5] += w*z;
+# endif
+#endif /* 3D */
+}
+
+static void parabola_fit_solve (ParabolaFit * p)
+{
+#if FTT_2D
+  p->M[0][1] = p->M[1][0];
+  p->M[0][2] = p->M[2][0] = p->M[1][1];
+  p->M[1][2] = p->M[2][1];
+  GtsMatrix * M = gts_matrix3_inverse ((GtsMatrix *) p->M);
+  if (M) {
+    p->a[0] = M[0][0]*p->rhs[0] + M[0][1]*p->rhs[1] + M[0][2]*p->rhs[2];
+    p->a[1] = M[1][0]*p->rhs[0] + M[1][1]*p->rhs[1] + M[1][2]*p->rhs[2];
+    gts_matrix_destroy (M);
+  }
+  else /* this may be a degenerate/isolated interface fragment */
+    p->a[0] = p->a[1] = 0.;
+#else /* 3D */
+# if PARABOLA_SIMPLER
+  p->M[0][1] = p->M[1][0]; p->M[0][2] = p->M[2][0];
+  p->M[1][2] = p->M[2][1]; p->M[2][2] = p->M[1][0];
+  GtsMatrix * M = gts_matrix3_inverse ((GtsMatrix *) p->M);
+  if (M) {
+    p->a[0] = M[0][0]*p->rhs[0] + M[0][1]*p->rhs[1] + M[0][2]*p->rhs[2];
+    p->a[1] = M[1][0]*p->rhs[0] + M[1][1]*p->rhs[1] + M[1][2]*p->rhs[2];
+    p->a[2] = M[2][0]*p->rhs[0] + M[2][1]*p->rhs[1] + M[2][2]*p->rhs[2];
+    gts_matrix_destroy (M);
+  }
+  else /* this may be a degenerate/isolated interface fragment */
+    p->a[0] = p->a[1] = p->a[2] = 0.;
+# else
+  p->M[0][1] = p->M[2][2]; p->M[0][5] = p->M[3][3];
+  p->M[1][5] = p->M[4][4];
+  p->M[2][3] = p->M[0][4]; p->M[2][4] = p->M[1][3];
+  p->M[3][4] = p->M[2][5];
+  guint i, j;
+  for (i = 1; i < 6; i++)
+    for (j = 0; j < i; j++)
+      p->M[i][j] = p->M[j][i];
+  if (gfs_matrix_inverse (p->M, 6, 1e-10)) {
+    for (i = 0; i < 6; i++) {
+      p->a[i] = 0.;
+      for (j = 0; j < 6; j++)
+	p->a[i] += p->M[i][j]*p->rhs[j];
+    }
+  }
+  else { /* this may be a degenerate/isolated interface fragment */
+    g_warning ("singular matrix");
+    p->a[0] = p->a[1] = p->a[2] = 0.;
+  }
+# endif
+#endif /* 3D */
+}
+
+static gdouble parabola_fit_curvature (ParabolaFit * p, gdouble kappamax,
+				       gdouble * kmax)
+{
+  gdouble kappa;
+#if FTT_2D
+  gdouble dnm = 1. + p->a[1]*p->a[1];
+  kappa = 2.*p->a[0]/sqrt (dnm*dnm*dnm);
+  if (kmax)
+    *kmax = fabs (kappa);
+#else /* 3D */
+  gdouble hxx = 2.*p->a[0];
+  gdouble hyy = 2.*p->a[1];
+  gdouble hxy = p->a[2];
+  gdouble hx, hy;
+# if PARABOLA_SIMPLER
+  hx = hy = 0.;
+# else
+  hx = p->a[3];
+  hy = p->a[4];
+# endif
+  gdouble dnm = 1. + hx*hx + hy*hy;
+  kappa = (hxx + hyy + hxx*hy*hy + hyy*hx*hx - 2.*hxy*hx*hy)/sqrt (dnm*dnm*dnm);
+  if (kmax) {
+    gdouble kg = (hxx*hyy - hxy*hxy)/(dnm*dnm);
+    gdouble a = kappa*kappa/4. - kg;
+    *kmax = fabs (kappa/2.);
+    if (a >= 0.)
+      *kmax += sqrt (a);
+  }
+#endif /* 3D */
+  if (fabs (kappa) > kappamax) {
+    if (kmax)
+      *kmax = kappamax;
+    return kappa > 0. ? kappamax : - kappamax;
+  }
+  return kappa;
+}
+
+#if FTT_2D
+static void parabola_fit_axi_curvature (const ParabolaFit * p, gdouble r, 
+					gdouble * kappa, gdouble * kmax)
+{
+  gdouble nr = (p->m[0]*p->a[1] + p->m[1])/sqrt (1. + p->a[1]*p->a[1]);
+  gdouble kaxi = - nr/r;
+  *kappa += kaxi;
+  if (kmax)
+    *kmax = MAX (*kmax, fabs (kaxi));
+}
+#endif /* 2D */
+
+static void parabola_fit_destroy (ParabolaFit * p)
+{
+#if (FTT_2D || PARABOLA_SIMPLER)
+  gts_matrix_destroy (p->M);
+#else
+  gfs_matrix_free (p->M);
+#endif
+}
+
+static void add_vof_center (FttCell * cell, FttVector * p, guint level,
+			    FttVector * origin,
+			    GfsVariableTracerVOF * t,
+			    ParabolaFit * fit, gdouble w)
+{
+  gdouble f = GFS_VALUE (cell, GFS_VARIABLE1 (t));
+  if (!GFS_IS_FULL (f)) {
+    FttVector m, c;
+    gdouble alpha = gfs_vof_plane_interpolate (cell, p, level, t, &m);
+    gdouble area = gfs_plane_area_center (&m, alpha, &c);
+    gdouble h = ftt_level_size (level);
+    FttComponent i;
+    for (i = 0; i < FTT_DIMENSION; i++)
+      (&c.x)[i] = ((&p->x)[i] - (&origin->x)[i])/h + (&c.x)[i] - 0.5;
+    parabola_fit_add (fit, &c.x, w*area);
+  }
+}
+
+static void fit_from_fractions (FttCell * cell, GfsVariable * v, ParabolaFit * fit)
+{
+  gdouble h = ftt_cell_size (cell);
+  guint level = ftt_cell_level (cell);
+  gint x, y, z = 0;
+  FttVector p;
+  
+  ftt_cell_pos (cell, &p);
+#if !FTT_2D
+  for (z = -1; z <= 1; z++)
+#endif
+    for (x = -1; x <= 1; x++)
+      for (y = -1; y <= 1; y++)
+	if (x != 0 || y != 0 || z != 0) {
+	  FttVector o;
+	  o.x = p.x + h*x; o.y = p.y + h*y; o.z = p.z + h*z;
+	  FttCell * neighbor = gfs_domain_boundary_locate (v->domain, o, level, NULL);
+	  if (neighbor)
+	    add_vof_center (neighbor, &o, level, &p, GFS_VARIABLE_TRACER_VOF (v),
+			    fit, 1.);
+	}
+}
+
+/**
+ * gfs_fit_curvature:
+ * @cell: a #FttCell containing an interface.
+ * @v: a #GfsVariableTracerVOF.
+ * @kmax: a pointer or %NULL. 
+ *
+ * Computes an approximation of the curvature of the interface
+ * contained in @cell using paraboloid fitting of the centroids of the
+ * reconstructed interface segments.
+ *
+ * If @kmax is not %NULL, it is filled with the absolute value of the
+ * maximum surface curvature (note that in 2D this is just the absolute value of
+ * the mean curvature).
+ *
+ * Returns: (double in 3D) the mean curvature of the interface contained in @cell.
+ */
+gdouble gfs_fit_curvature (FttCell * cell, GfsVariableTracerVOF * t, gdouble * kmax)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  g_return_val_if_fail (!GFS_IS_FULL (GFS_VALUE (cell,  v)), 0.);
+
+  FttVector m;
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m.x)[c] = GFS_VALUE (cell, t->m[c]);
+
+  ParabolaFit fit;
+  FttVector p, fc;
+  ftt_cell_pos (cell, &p);
+  gdouble area = gfs_vof_center (cell, t, &fc);
+  gdouble h = ftt_cell_size (cell);
+  fc.x = (fc.x - p.x)/h;
+  fc.y = (fc.y - p.y)/h;
+  fc.z = (fc.z - p.z)/h;
+  parabola_fit_init (&fit, &fc, &m);
+  parabola_fit_add (&fit, &fc.x, area);
+  fit_from_fractions (cell, GFS_VARIABLE1 (t), &fit);
+  parabola_fit_solve (&fit);
+  gdouble kappa = parabola_fit_curvature (&fit, 2., kmax)/h;
+  if (kmax)
+    *kmax /= h;
+#if FTT_2D
+  if (GFS_IS_AXI (v->domain))
+    parabola_fit_axi_curvature (&fit, fc.y*h + p.y, &kappa, kmax);
+#endif
+  parabola_fit_destroy (&fit);
+  return kappa;
+}
+
+#if FTT_2D
+# define NI 3
+#else
+# define NI 9
+#endif
+
+static void orientation (FttVector * m, FttComponent * c)
+{
+  FttComponent i, j;
+  for (i = 0; i < FTT_DIMENSION; i++)
+    c[i] = i;
+  for (i = 0; i < FTT_DIMENSION - 1; i++)
+    for (j = 0; j < FTT_DIMENSION - 1 - i; j++)
+      if (fabs ((&m->x)[c[j + 1]]) > fabs ((&m->x)[c[j]])) {
+	FttComponent tmp = c[j];
+	c[j] = c[j + 1];
+	c[j + 1] = tmp;
+      }
+}
+
+static guint independent_positions (GtsVector * interface, guint n)
+{
+  if (n < 2)
+    return n;
+
+  guint j, ni = 1;
+  for (j = 1; j < n; j++) {
+    guint i;
+    gboolean depends = FALSE;
+    for (i = 0; i < j && !depends; i++) {
+      gdouble d2 = 0.;
+      FttComponent c;
+      for (c = 0; c < FTT_DIMENSION; c++)
+	d2 += (interface[i][c] - interface[j][c])*(interface[i][c] - interface[j][c]);
+      depends = d2 < 0.5*0.5;
+    }
+    ni += !depends;
+  }
+  return ni;
+}
+
+/**
+ * gfs_height_curvature:
+ * @cell: a #FttCell containing an interface.
+ * @v: a #GfsVariableTracerVOF.
+ * @kmax: a pointer or %NULL.
+ *
+ * An implementation of the Height-Function (HF) method generalised to
+ * adaptive meshes.
+ *
+ * If @kmax is not %NULL, it is filled with the absolute value of the
+ * maximum surface curvature (note that in 2D this is just the absolute value of
+ * the mean curvature).
+ *
+ * Returns: (double in 3D) the mean curvature of the interface contained in @cell.
+ */
+gdouble gfs_height_curvature (FttCell * cell, GfsVariableTracerVOF * t, gdouble * kmax)
+{
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  gdouble f = GFS_VALUE (cell,  v);
+  g_return_val_if_fail (!GFS_IS_FULL (f), 0.);
+
+  FttVector m;
+  FttComponent c;
+  for (c = 0; c < FTT_DIMENSION; c++)
+    (&m.x)[c] = GFS_VALUE (cell, t->m[c]);
+
+  FttComponent try[FTT_DIMENSION];
+  orientation (&m, try); /* sort directions according to normal */
+
+  gdouble kappa = 0.;
+  GtsVector interface[FTT_DIMENSION*NI];
+  guint n = 0;
+  for (c = 0; c < FTT_DIMENSION; c++) /* try each direction */
+    if (curvature_along_direction (cell, t, try[c], &kappa, kmax, interface, &n))
+      return kappa;
+
+  /* Could not compute curvature from the simple algorithm along any direction:
+   * Try parabola fitting of the collected interface positions */
+
+  if (independent_positions (interface, n) < 3*(FTT_DIMENSION - 1))
+    return G_MAXDOUBLE;
+
+  gdouble h = ftt_cell_size (cell);
+  ParabolaFit fit;
+  guint j;
+  
+  FttVector p, fc;
+  ftt_cell_pos (cell, &p);
+  gdouble area = gfs_vof_center (cell, t, &fc);
+  fc.x = (fc.x - p.x)/h;
+  fc.y = (fc.y - p.y)/h;
+  fc.z = (fc.z - p.z)/h;
+  parabola_fit_init (&fit, &fc, &m);
+#if FTT_2D
+  parabola_fit_add (&fit, &fc.x, PARABOLA_FIT_CENTER_WEIGHT);
+#elif !PARABOLA_SIMPLER
+  parabola_fit_add (&fit, &fc.x, area*100.);
+#endif
+  for (j = 0; j < n; j++)
+    parabola_fit_add (&fit, interface[j], 1.);
+  parabola_fit_solve (&fit);
+  kappa = parabola_fit_curvature (&fit, 2., kmax)/h;
+  if (kmax)
+    *kmax /= h;
+#if FTT_2D
+  if (GFS_IS_AXI (v->domain))
+    parabola_fit_axi_curvature (&fit, fc.y*h + p.y, &kappa, kmax);
+#endif
+  parabola_fit_destroy (&fit);
+  return kappa;
+}
+
+/**
+ * gfs_vof_correctness:
+ * @cell: a #FttCell.
+ * @t: a #GfsVariableTracerVOF.
+ *
+ * An implementation of the criterion of Cerne et al (2002), to
+ * measure how well an interface is represented by a local VOF field.
+ *
+ * Returns: the "correctness" of the interface representation.
+ */
+gdouble gfs_vof_correctness (FttCell * cell, GfsVariableTracerVOF * t)
+{
+  GfsVariable * v = GFS_VARIABLE1 (t);
+  gdouble F(3,3,3);
+  
+  g_return_val_if_fail (cell != NULL, 0.);
+  g_return_val_if_fail (t != NULL, 0.);
+
+  if (GFS_VALUE (cell, v) <= 0. || GFS_VALUE (cell, v) >= 1.)
+    return 1.;
+
+  stencil (cell, v, f);
+#if FTT_2D
+  gdouble dx = f[2][0] + f[2][1] + f[2][2] - f[0][0] - f[0][1] - f[0][2];
+  gdouble dy = f[0][2] + f[1][2] + f[2][2] - f[0][0] - f[1][0] - f[2][0];
+  return sqrt ((dx*dx + dy*dy)/9.);
+#else
+  gdouble dx = (f[2][0][0] + f[2][1][0] + f[2][2][0] - f[0][0][0] - f[0][1][0] - f[0][2][0] +
+		f[2][0][1] + f[2][1][1] + f[2][2][1] - f[0][0][1] - f[0][1][1] - f[0][2][1] +
+		f[2][0][2] + f[2][1][2] + f[2][2][2] - f[0][0][2] - f[0][1][2] - f[0][2][2]);
+  gdouble dy = (f[0][2][0] + f[1][2][0] + f[2][2][0] - f[0][0][0] - f[1][0][0] - f[2][0][0] +
+		f[0][2][1] + f[1][2][1] + f[2][2][1] - f[0][0][1] - f[1][0][1] - f[2][0][1] +
+		f[0][2][2] + f[1][2][2] + f[2][2][2] - f[0][0][2] - f[1][0][2] - f[2][0][2]);
+  gdouble dz = (f[0][0][2] + f[1][0][2] + f[2][0][2] - f[0][0][0] - f[1][0][0] - f[2][0][0] +
+		f[0][1][2] + f[1][1][2] + f[2][1][2] - f[0][1][0] - f[1][1][0] - f[2][1][0] +
+		f[0][2][2] + f[1][2][2] + f[2][2][2] - f[0][2][0] - f[1][2][0] - f[2][2][0]);  
+  return sqrt ((dx*dx + dy*dy + dz*dz)/27.);
+#endif
+}
diff --git a/src/vof.h b/src/vof.h
new file mode 100644
index 0000000..b54b788
--- /dev/null
+++ b/src/vof.h
@@ -0,0 +1,121 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __VOF_H__
+#define __VOF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "advection.h"
+#include "variable.h"
+
+#define GFS_IS_FULL(f)             ((f) == 0. || (f) == 1.)
+
+gdouble gfs_line_area              (const FttVector * m, 
+				    gdouble alpha);
+void    gfs_line_center            (const FttVector * m, 
+				    gdouble alpha, 
+				    gdouble a, 
+				    FttVector * p);
+gdouble gfs_line_area_center       (const FttVector * m, 
+				    gdouble alpha, 
+				    FttVector * p);
+gdouble gfs_line_alpha             (const FttVector * m, 
+				    gdouble c);
+#if FTT_2D
+#  define gfs_plane_volume         gfs_line_area
+#  define gfs_plane_alpha          gfs_line_alpha
+#  define gfs_plane_center         gfs_line_center
+#  define gfs_plane_area_center     gfs_line_area_center
+#else /* 3D */
+gdouble gfs_plane_volume           (const FttVector * m, 
+				    gdouble alpha);
+gdouble gfs_plane_alpha            (const FttVector * m, 
+				    gdouble c);
+void    gfs_plane_center           (const FttVector * m, 
+				    gdouble alpha, 
+				    gdouble a,
+				    FttVector * p);
+gdouble gfs_plane_area_center      (const FttVector * m, 
+				    gdouble alpha, 
+				    FttVector * p);
+#endif /* 3D */
+void    gfs_youngs_gradient        (FttCell * cell, 
+				    GfsVariable * v,
+				    FttVector * g);
+
+/* GfsVariableTracerVOF: header */
+
+typedef struct _GfsVariableTracerVOF                GfsVariableTracerVOF;
+
+struct _GfsVariableTracerVOF {
+  /*< private >*/
+  GfsVariableTracer parent;
+
+  /*< public >*/
+  GfsVariable * m[FTT_DIMENSION], * alpha;
+};
+
+#define GFS_VARIABLE_TRACER_VOF(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsVariableTracerVOF,\
+					           gfs_variable_tracer_vof_class ())
+#define GFS_IS_VARIABLE_TRACER_VOF(obj)         (gts_object_is_from_class (obj,\
+						   gfs_variable_tracer_vof_class ()))
+
+GfsVariableClass * gfs_variable_tracer_vof_class  (void);
+
+void     gfs_tracer_vof_advection  (GfsDomain * domain,
+				    GfsAdvectionParams * par);
+gdouble  gfs_vof_face_value        (const FttCellFace * face, 
+				    GfsVariableTracerVOF * t);
+guint    gfs_vof_facet             (FttCell * cell,
+				    GfsVariableTracerVOF * t,
+				    FttVector * p,
+				    FttVector * m);
+gdouble  gfs_vof_facet_distance2   (FttCell * cell,
+				    GfsVariableTracerVOF * t,
+				    GtsPoint * p);
+gdouble  gfs_vof_center            (FttCell * cell,
+				    GfsVariableTracerVOF * t,
+				    FttVector * p);
+gdouble  gfs_vof_plane_interpolate (FttCell * cell,
+				    FttVector * p,
+				    guint level,
+				    GfsVariableTracerVOF * t,
+				    FttVector * m);
+gdouble  gfs_vof_interpolate       (FttCell * cell,
+				    FttVector * p,
+				    guint level,
+				    GfsVariableTracerVOF * t);
+gdouble  gfs_height_curvature      (FttCell * cell, 
+				    GfsVariableTracerVOF * t,
+				    gdouble * kmax);
+gdouble  gfs_fit_curvature         (FttCell * cell,
+				    GfsVariableTracerVOF * t,
+				    gdouble * kmax);
+gdouble  gfs_vof_correctness       (FttCell * cell, 
+				    GfsVariableTracerVOF * t);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __VOF_H__ */
diff --git a/src/wave.c b/src/wave.c
new file mode 100644
index 0000000..05c61c3
--- /dev/null
+++ b/src/wave.c
@@ -0,0 +1,485 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2008 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "wave.h"
+#include "adaptive.h"
+#include "solid.h"
+
+/* GfsWave: Object */
+
+static double frequency (int ik)
+{
+  double gamma = GFS_WAVE_GAMMA;
+  double f0 = GFS_WAVE_F0;
+  return f0*pow(gamma, ik);
+}
+      
+static double theta (guint ith, guint ntheta)
+{
+  return 2.*M_PI*ith/ntheta;
+}
+
+static void group_velocity (int ik, int ith, FttVector * u, guint ntheta, gdouble g)
+{
+  double cg = g/(4.*M_PI*frequency (ik));
+  u->x = cg*cos (theta (ith, ntheta));
+  u->y = cg*sin (theta (ith, ntheta));
+  u->z = 0.;
+}
+
+static gdouble cell_E (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  GfsWave * wave = GFS_WAVE (domain);
+  GfsVariable *** F = wave->F;
+  guint ik, ith;
+  gdouble E = 0., sigma = 2.*M_PI*GFS_WAVE_F0, sgamma = (GFS_WAVE_GAMMA - 1./GFS_WAVE_GAMMA)/2.;
+  for (ik = 0; ik < wave->nk; ik++) {
+    gdouble df = sigma*sgamma;
+    gdouble dE = 0.;
+    for (ith = 0; ith < wave->ntheta; ith++)
+      dE += GFS_VALUE (cell, F[ik][ith]);
+    E += dE*df;
+    sigma *= GFS_WAVE_GAMMA;
+  }
+  return E*2.*M_PI/wave->ntheta;
+}
+
+static void set_group_velocity (const FttCellFace * face, FttVector * u)
+{
+  GFS_FACE_NORMAL_VELOCITY_RIGHT (face) = 
+    GFS_FACE_NORMAL_VELOCITY_LEFT (face) = (&u->x)[face->d/2];
+}
+
+typedef struct {
+  GfsAdvectionParams * p;
+  GfsVariable * div, * fv;
+} SolidFluxParams;
+
+static void solid_flux (FttCell * cell, SolidFluxParams * par)
+{
+  gfs_normal_divergence (cell, par->div);
+  if (GFS_VALUE (cell, par->div) < 0.) {
+    gdouble h = ftt_cell_size (cell);
+    GFS_VALUE (cell, par->fv) = GFS_VALUE (cell, par->div)*par->p->dt*
+      GFS_VALUE (cell, par->p->v)/(h*h);
+  }
+  else
+    GFS_VALUE (cell, par->fv) = 0.;
+}
+
+typedef struct {
+  GfsVariable * F, * Fn, * dF;
+  gdouble D[2][2];
+} GSEData;
+
+static void compute_gradient (FttCell * cell, GSEData * p)
+{
+  GFS_VALUE (cell, p->dF) = gfs_center_regular_gradient (cell, p->dF->component, p->Fn);
+}
+
+static void diffusion (FttCell * cell, GSEData * p)
+{
+  gdouble h2 = ftt_cell_size (cell);
+  h2 *= h2;
+  /* off-diagonal */
+  FttComponent j;
+  for (j = 0; j < 2; j++)
+    if (j != p->dF->component)
+      GFS_VALUE (cell, p->F) += 
+	p->D[j][p->dF->component]*gfs_center_regular_gradient (cell, j, p->dF)/h2;
+  /* diagonal */
+  GFS_VALUE (cell, p->F) += 
+    p->D[p->dF->component][p->dF->component]*
+    gfs_center_regular_2nd_derivative (cell, p->dF->component, p->Fn)/h2;
+}
+
+static void copy_F (FttCell * cell, GSEData * p)
+{
+  GFS_VALUE (cell, p->Fn) = GFS_VALUE (cell, p->F);
+}
+
+static void gse_alleviation_diffusion (GfsDomain * domain, GfsVariable * F,
+				       FttVector * cg, gdouble dt)
+{
+  gfs_domain_timer_start (domain, "gse_alleviation");
+
+  gdouble ncg = sqrt (cg->x*cg->x + cg->y*cg->y);
+  gdouble dcg = (GFS_WAVE_GAMMA - 1./GFS_WAVE_GAMMA)*ncg/2.;
+  gdouble dtheta = 2.*M_PI/GFS_WAVE (domain)->ntheta;
+#if 0
+  gdouble Ts = 4.*GFS_WAVE (domain)->alpha_s*GFS_WAVE (domain)->alpha_s*dt;
+  gdouble dtDss = dt*dcg*dcg*Ts/12.;
+  gdouble dtDnn = dt*(ncg*dtheta)*(ncg*dtheta)*Ts/12.;
+#else
+  gdouble alpha = GFS_WAVE (domain)->alpha_s*dcg*dt;
+  gdouble beta = GFS_WAVE (domain)->alpha_s*ncg*dtheta*dt;
+  gdouble dtDss = alpha*alpha/3.;
+  gdouble dtDnn = beta*beta/3.;
+#endif
+  GSEData p;
+  gdouble cost = cg->x/ncg, sint = cg->y/ncg;
+  p.D[0][0] = dtDss*cost*cost + dtDnn*sint*sint;
+  p.D[1][1] = dtDss*sint*sint + dtDnn*cost*cost;
+  p.D[0][1] = p.D[1][0] = (dtDss - dtDnn)*cost*sint;
+  p.F = F;
+  p.Fn = gfs_temporary_variable (domain);
+  p.dF = gfs_temporary_variable (domain);
+  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) copy_F, &p);
+  gfs_domain_cell_traverse (domain, FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			    (FttCellTraverseFunc) p.Fn->fine_coarse, p.Fn);
+  for (p.dF->component = 0; p.dF->component < 2; p.dF->component++) {
+    gfs_domain_cell_traverse (domain,  FTT_PRE_ORDER, FTT_TRAVERSE_ALL, -1,
+			      (FttCellTraverseFunc) compute_gradient, &p);
+    gfs_domain_bc (domain, FTT_TRAVERSE_ALL, -1, p.dF);
+    gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) diffusion, &p);
+  }
+  gts_object_destroy (GTS_OBJECT (p.Fn));
+  gts_object_destroy (GTS_OBJECT (p.dF));
+  gfs_domain_timer_stop (domain, "gse_alleviation");
+}
+
+static void redo_some_events (GfsEvent * event, GfsSimulation * sim)
+{
+  if (GFS_IS_ADAPT (event) || GFS_IS_INIT (event))
+    gfs_event_redo (event, sim);
+}
+
+static void wave_run (GfsSimulation * sim)
+{
+  GfsDomain * domain = GFS_DOMAIN (sim);
+  GfsWave * wave = GFS_WAVE (sim);
+
+  SolidFluxParams par;
+  par.div = gfs_variable_from_name (domain->variables, "P");
+  g_assert (par.div);
+  par.p = &sim->advection_params;
+  par.fv = gfs_temporary_variable (domain);
+
+  gfs_simulation_refine (sim);
+  gfs_simulation_init (sim);
+
+  while (sim->time.t < sim->time.end &&
+	 sim->time.i < sim->time.iend) {
+    gdouble tstart = gfs_clock_elapsed (domain->timer);
+
+    gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);
+
+    /* get global timestep */
+    gfs_domain_face_traverse (domain, FTT_XYZ,
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttFaceTraverseFunc) gfs_face_reset_normal_velocity, NULL);
+    gfs_simulation_set_timestep (sim);
+    gdouble dt = sim->advection_params.dt;
+    gdouble g = sim->physical_params.g/sim->physical_params.L;
+    gdouble tnext = sim->tnext;
+    
+    /* spatial advection */
+    guint ik, ith;
+    for (ik = 0; ik < wave->nk; ik++) {
+      FttVector cg;
+      group_velocity (ik, 0, &cg, wave->ntheta, g);
+      gfs_domain_face_traverse (domain, FTT_XYZ,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttFaceTraverseFunc) set_group_velocity, &cg);
+      if (wave->alpha_s > 0.) {
+	/* stability criterion for GSE diffusion */
+	gdouble cfl = sim->advection_params.cfl;
+	sim->advection_params.cfl = MIN (cfl, 2./(4.*wave->alpha_s*M_PI/wave->ntheta));
+	/* fixme: this should be:
+	   sim->advection_params.cfl = MIN (cfl, sqrt(3.)/(wave->alpha_s*2.*M_PI/wave->ntheta));
+	*/
+	gfs_simulation_set_timestep (sim);
+	sim->advection_params.cfl = cfl;
+      }
+      else
+	gfs_simulation_set_timestep (sim);
+      /* subcycling */
+      guint n = rint (dt/sim->advection_params.dt);
+      g_assert (fabs (sim->time.t + sim->advection_params.dt*n - tnext) < 1e-12);
+      while (n--) {
+	for (ith = 0; ith < wave->ntheta; ith++) {
+	  FttVector cg;
+	  group_velocity (ik, ith, &cg, wave->ntheta, g);
+	  gfs_domain_face_traverse (domain, FTT_XYZ,
+				    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				    (FttFaceTraverseFunc) set_group_velocity, &cg);
+	  GfsVariable * t = GFS_WAVE (sim)->F[ik][ith];
+	  sim->advection_params.v = t;
+	  gfs_domain_traverse_leaves (domain, (FttCellTraverseFunc) solid_flux, &par);
+	  gfs_tracer_advection_diffusion (domain, &sim->advection_params);
+	  sim->advection_params.fv = par.fv;
+	  gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) gfs_advection_update, 
+	  			      &sim->advection_params);
+	  if (wave->alpha_s > 0.)
+	    gse_alleviation_diffusion (domain, t, &cg, sim->advection_params.dt);
+	  gfs_domain_bc (domain, FTT_TRAVERSE_LEAFS, -1, t);
+	  gfs_domain_cell_traverse (domain,
+				    FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				    (FttCellTraverseFunc) t->fine_coarse, t);
+	}
+	gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) redo_some_events, sim);
+	gfs_simulation_adapt (sim);
+      }
+    }
+
+    sim->advection_params.dt = dt;
+
+    /* source terms */
+    if (wave->source)
+      (* wave->source) (wave);
+
+    sim->time.t = sim->tnext = tnext;
+    sim->time.i++;
+
+    gts_range_add_value (&domain->timestep, gfs_clock_elapsed (domain->timer) - tstart);
+    gts_range_update (&domain->timestep);
+    gts_range_add_value (&domain->size, gfs_domain_size (domain, FTT_TRAVERSE_LEAFS, -1));
+    gts_range_update (&domain->size);
+  }
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gfs_event_do, sim);  
+  gts_container_foreach (GTS_CONTAINER (sim->events), (GtsFunc) gts_object_destroy, NULL);
+  gts_object_destroy (GTS_OBJECT (par.fv));
+}
+
+static void wave_destroy (GtsObject * object)
+{
+  if (GFS_WAVE (object)->F)
+    gfs_matrix_free (GFS_WAVE (object)->F);
+  (* GTS_OBJECT_CLASS (gfs_wave_class ())->parent_class->destroy) (object);
+}
+
+static void wave_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_wave_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsWave * wave = GFS_WAVE (*o);
+  if (fp->type == '{') {
+    GtsFileVariable var[] = {
+      {GTS_UINT,   "nk",      TRUE, &wave->nk},
+      {GTS_UINT,   "ntheta",  TRUE, &wave->ntheta},
+      {GTS_DOUBLE, "alpha_s", TRUE, &wave->alpha_s},
+      {GTS_NONE}
+    };
+    gts_file_assign_variables (fp, var);
+    if (fp->type == GTS_ERROR)
+      return;
+  }
+
+  GfsDomain * domain = GFS_DOMAIN (wave);
+  guint ik, ith;
+  wave->F = gfs_matrix_new (wave->nk, wave->ntheta, sizeof (GfsVariable *));
+  for (ik = 0; ik < wave->nk; ik++)
+    for (ith = 0; ith < wave->ntheta; ith++) {
+      gchar * name = g_strdup_printf ("F%d_%d", ik, ith);
+      gchar * description = g_strdup_printf ("Action density for f = %g Hz and theta = %g degrees",
+					     frequency (ik), theta (ith, wave->ntheta)*180./M_PI);
+      wave->F[ik][ith] = gfs_domain_get_or_add_variable (domain, name, description);
+      g_assert (wave->F[ik][ith]);
+      g_free (name);
+      g_free (description);
+    }
+}
+
+static void wave_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_wave_class ())->parent_class->write) (o, fp);
+
+  GfsWave * wave = GFS_WAVE (o);
+  fprintf (fp, " {\n"
+	   "  nk = %d\n"
+	   "  ntheta = %d\n"
+	   "  alpha_s = %g\n"
+	   "}",
+	   wave->nk, wave->ntheta, wave->alpha_s);
+}
+
+static void gfs_wave_class_init (GfsSimulationClass * klass)
+{
+  GTS_OBJECT_CLASS (klass)->destroy = wave_destroy;
+  GTS_OBJECT_CLASS (klass)->read = wave_read;
+  GTS_OBJECT_CLASS (klass)->write = wave_write;
+  klass->run = wave_run;
+}
+
+static gdouble cell_hs (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  gdouble E = cell_E (cell, face, domain);
+  return E > 0. ? 4.*sqrt (E) : 0.;
+}
+
+static gdouble cell_frequency (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return frequency (GFS_WAVE (domain)->ik);
+}
+
+static gdouble cell_direction (FttCell * cell, FttCellFace * face, GfsDomain * domain)
+{
+  return theta (GFS_WAVE (domain)->ith, GFS_WAVE (domain)->ntheta);
+}
+
+static void wave_init (GfsWave * wave)
+{
+  wave->nk = 25;
+  wave->ntheta = 24;
+  wave->alpha_s = 0.;
+  /* default for g is acceleration of gravity on Earth with kilometres as
+     spatial units, hours as time units and Hz as frequency units */
+  GFS_SIMULATION (wave)->physical_params.g = 9.81/1000.*3600.;
+
+  GfsAdvectionParams * par = &GFS_SIMULATION (wave)->advection_params;
+  par->gradient = gfs_center_van_leer_gradient;
+  par->flux = gfs_face_advection_flux;
+  par->use_centered_velocity = FALSE;  
+
+  static GfsDerivedVariableInfo derived_variable[] = {
+    { "Hs", "Significant wave height", cell_hs },
+    { "Energy", "Wave energy", cell_E },
+    { "Frequency", "Wave frequency", cell_frequency },
+    { "Direction", "Wave direction (angle)", cell_direction },
+    { NULL, NULL, NULL}
+  };
+  GfsDerivedVariableInfo * v = derived_variable;
+  while (v->name) {
+    g_assert (gfs_domain_add_derived_variable (GFS_DOMAIN (wave), *v));
+    v++;
+  }
+}
+
+GfsSimulationClass * gfs_wave_class (void)
+{
+  static GfsSimulationClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_wave_info = {
+      "GfsWave",
+      sizeof (GfsWave),
+      sizeof (GfsSimulationClass),
+      (GtsObjectClassInitFunc) gfs_wave_class_init,
+      (GtsObjectInitFunc) wave_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_simulation_class ()), &gfs_wave_info);
+  }
+
+  return klass;
+}
+
+/* GfsInitWave: Object */
+
+static void gfs_init_wave_read (GtsObject ** o, GtsFile * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_init_wave_class ())->parent_class->read) (o, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+
+  GfsDomain * domain = GFS_DOMAIN (gfs_object_simulation (*o));
+  if (!GFS_IS_WAVE (domain)) {
+    gts_file_error (fp, "GfsInitWave can only be used within a GfsWave simulation");
+    return;
+  }
+  
+  gfs_function_read (GFS_INIT_WAVE (*o)->d, domain, fp);
+  if (fp->type == GTS_ERROR)
+    return;
+  gfs_function_read (GFS_INIT_WAVE (*o)->hs, domain, fp);
+}
+
+static void gfs_init_wave_write (GtsObject * o, FILE * fp)
+{
+  (* GTS_OBJECT_CLASS (gfs_init_wave_class ())->parent_class->write) (o, fp);
+
+  gfs_function_write (GFS_INIT_WAVE (o)->d, fp);
+  gfs_function_write (GFS_INIT_WAVE (o)->hs, fp);
+}
+
+static void gfs_init_wave_destroy (GtsObject * object)
+{
+  gts_object_destroy (GTS_OBJECT (GFS_INIT_WAVE (object)->d));
+  gts_object_destroy (GTS_OBJECT (GFS_INIT_WAVE (object)->hs));
+
+  (* GTS_OBJECT_CLASS (gfs_init_wave_class ())->parent_class->destroy) (object);
+}
+
+static void init_energy (FttCell * cell, GfsInitWave * event)
+{
+  GfsWave * wave = GFS_WAVE (gfs_object_simulation (event));
+  for (wave->ik = 0; wave->ik < wave->nk; wave->ik++)
+    for (wave->ith = 0; wave->ith < wave->ntheta; wave->ith++)
+      GFS_VALUE (cell, wave->F[wave->ik][wave->ith]) = gfs_function_value (event->d, cell);
+
+  gdouble E = cell_E (cell, NULL, GFS_DOMAIN (wave));
+  if (E > 0.) {
+    gdouble Hs = gfs_function_value (event->hs, cell);
+    gdouble scaling = Hs*Hs/(16.*E);
+    guint ik, ith;
+    for (ik = 0; ik < wave->nk; ik++)
+      for (ith = 0; ith < wave->ntheta; ith++)
+	GFS_VALUE (cell, wave->F[ik][ith]) *= scaling;
+  }
+}
+
+static gboolean gfs_init_wave_event (GfsEvent * event, GfsSimulation * sim)
+{
+  if ((* GFS_EVENT_CLASS (GTS_OBJECT_CLASS (gfs_init_wave_class ())->parent_class)->event) 
+      (event, sim)) {
+    gfs_domain_cell_traverse (GFS_DOMAIN (sim), FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) init_energy, event);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void gfs_init_wave_class_init (GfsGenericInitClass * klass)
+{
+  GFS_EVENT_CLASS (klass)->event = gfs_init_wave_event;
+  GTS_OBJECT_CLASS (klass)->read = gfs_init_wave_read;
+  GTS_OBJECT_CLASS (klass)->write = gfs_init_wave_write;
+  GTS_OBJECT_CLASS (klass)->destroy = gfs_init_wave_destroy;
+}
+
+static void gfs_init_wave_init (GfsInitWave * object)
+{
+  object->d = gfs_function_new (gfs_function_class (), 0.);
+  object->hs = gfs_function_new (gfs_function_class (), 0.);
+}
+
+GfsGenericInitClass * gfs_init_wave_class (void)
+{
+  static GfsGenericInitClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_init_wave_info = {
+      "GfsInitWave",
+      sizeof (GfsInitWave),
+      sizeof (GfsGenericInitClass),
+      (GtsObjectClassInitFunc) gfs_init_wave_class_init,
+      (GtsObjectInitFunc) gfs_init_wave_init,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gfs_generic_init_class ()),
+				  &gfs_init_wave_info);
+  }
+
+  return klass;
+}
+
diff --git a/src/wave.h b/src/wave.h
new file mode 100644
index 0000000..545ebf7
--- /dev/null
+++ b/src/wave.h
@@ -0,0 +1,80 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __WAVE_H__
+#define __WAVE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "simulation.h"
+
+/* GfsWave: Header */
+
+#define GFS_WAVE_GAMMA 1.1
+#define GFS_WAVE_F0 0.04
+
+typedef struct _GfsWave    GfsWave;
+
+struct _GfsWave {
+  /*< private >*/
+  GfsSimulation parent;
+  guint ik, ith;
+  void (* source) (GfsWave * wave);
+
+  /*< public >*/
+  guint nk, ntheta;
+  gdouble alpha_s;
+  GfsVariable *** F;
+};
+
+#define GFS_WAVE(obj)            GTS_OBJECT_CAST (obj,\
+					           GfsWave,\
+					           gfs_wave_class ())
+#define GFS_IS_WAVE(obj)         (gts_object_is_from_class (obj,\
+							    gfs_wave_class ()))
+
+GfsSimulationClass * gfs_wave_class        (void);
+
+/* GfsInitWave: Header */
+
+typedef struct _GfsInitWave         GfsInitWave;
+
+struct _GfsInitWave {
+  /*< private >*/
+  GfsGenericInit parent;
+
+  /*< public >*/
+  GfsFunction * d, * hs;
+};
+
+#define GFS_INIT_WAVE(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsInitWave,\
+					         gfs_init_wave_class ())
+#define GFS_IS_INIT_WAVE(obj)         (gts_object_is_from_class (obj,\
+						 gfs_init_wave_class ()))
+
+GfsGenericInitClass * gfs_init_wave_class  (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __WAVE_H__ */
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..94ac6ea
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,91 @@
+## Process this file with automake to produce Makefile.in
+
+TESTDIRS = \
+	poisson \
+	circle \
+	dumbell \
+	advection \
+	shear \
+	reynolds \
+	periodic \
+	merging \
+	axi \
+	axiadvection \
+	lid \
+	poiseuille \
+	couette \
+	kinetic \
+	hydrostatic \
+	boundaries \
+	channel \
+	plate \
+	hexagon \
+	strouhal \
+	spurious \
+	capwave \
+	oscillation \
+	geo \
+	waves \
+	nz \
+	parabola \
+	lonlat \
+	cosine
+
+EXTRA_DIST = \
+	template.tex \
+	tests.bib \
+	depend.py \
+	test.py \
+	check.py \
+	gfs2tex \
+	Makefile.deps
+
+TESTS = test.sh
+
+test.sh: $(TESTDIRS)
+	@echo "python -u test.py $(TESTDIRS)" > test.sh
+	@chmod +x test.sh
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out tests.tex *.pyc test.sh *.bbl *.blg Makefile.deps
+
+DOC = tests
+
+tests: tests.dvi
+	hevea -fix $(DOC).tex
+	imagen -res 500 -extra "pnmscale 0.24" $(DOC)
+	hacha $(DOC).html
+	rm -f $(DOC).html
+	mv -f $(DOC)[0-9][0-9][0-9].png $(DOC)
+##	fixme: the character conversion below is a workaround for a bug in hevea version < 1.09
+	for f in *.html; do konwert iso1-utf8 < $$f > $(DOC)/$$f; rm -f $$f; done
+	cat $(DOC).css ../doc/share/darcs.css > $(DOC)/$(DOC).css
+	sh ../doc/share/fixnav.sh $(DOC)
+	cp -f ../doc/share/contents.png ../doc/share/next.png ../doc/share/prev.png $(DOC)
+	rm -f *_motif.gif $(DOC).h{tml,aux,ind,toc} $(DOC).image.tex $(DOC).css
+	sh ../doc/examples/crossref.sh --url=http://gfs.sourceforge.net/tests/tests $(TESTDIRS)
+	mv references tests
+
+tests.dvi: tests.tex tests.bib
+	latex -interaction=nonstopmode tests.tex > /dev/null 2>&1
+	bibtex tests
+	latex -interaction=nonstopmode tests.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tests.tex
+
+tests.pdf: tests.dvi
+	dvips -Ppdf -G0 tests.dvi -o tests.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true tests.ps tests.pdf
+	rm -f tests.ps
+
+tests.tex: template.tex Makefile.deps
+	rm -r -f tests
+	python gfs2tex $(TESTDIRS)
+	cp -f template.tex tests.tex
+
+Makefile.deps: Makefile depend.py
+	python depend.py $(TESTDIRS) > Makefile.deps
+
+-include Makefile.deps
+
+tests.tar.gz: tests $(DOCS)
+	tar czf tests.tar.gz tests $(DOCS)
diff --git a/test/Makefile.deps b/test/Makefile.deps
new file mode 100644
index 0000000..e29a6d6
--- /dev/null
+++ b/test/Makefile.deps
@@ -0,0 +1,652 @@
+DOCS = \
+	poisson/poisson.gfs.html\
+	poisson/circle/circle.gfs.html\
+	circle/circle.gfs.html\
+	circle/refined/refined.gfs.html\
+	circle/star/star.gfs.html\
+	circle/thin/thin.gfs.html\
+	dumbell/dumbell.gfs.html\
+	advection/advection.gfs.html\
+	shear/shear.gfs.html\
+	shear/curvature/curvature.gfs.html\
+	reynolds/reynolds.gfs.html\
+	reynolds/box/box.gfs.html\
+	periodic/periodic.gfs.html\
+	merging/merging.gfs.html\
+	axi/axi.gfs.html\
+	axi/viscous/viscous.gfs.html\
+	axiadvection/axiadvection.gfs.html\
+	axiadvection/solid/solid.gfs.html\
+	lid/lid.gfs.html\
+	lid/explicit/explicit.gfs.html\
+	poiseuille/poiseuille.gfs.html\
+	couette/couette.gfs.html\
+	kinetic/kinetic.gfs.html\
+	hydrostatic/hydrostatic.gfs.html\
+	hydrostatic/quadratic/quadratic.gfs.html\
+	boundaries/boundaries.gfs.html\
+	channel/channel.gfs.html\
+	plate/plate.gfs.html\
+	hexagon/hexagon.gfs.html\
+	strouhal/strouhal.gfs.html\
+	spurious/spurious.gfs.html\
+	spurious/axi/axi.gfs.html\
+	capwave/capwave.gfs.html\
+	capwave/air-water/air-water.gfs.html\
+	capwave/density/density.gfs.html\
+	capwave/gravity/gravity.gfs.html\
+	oscillation/oscillation.gfs.html\
+	geo/geo.gfs.html\
+	geo/beta/beta.gfs.html\
+	waves/waves.gfs.html\
+	waves/adaptive/adaptive.gfs.html\
+	nz/nz.gfs.html\
+	parabola/parabola.gfs.html\
+	lonlat/lonlat.gfs.html\
+	lonlat/coriolis/coriolis.gfs.html\
+	cosine/cosine.gfs.html\
+	poisson/poisson.gfs\
+	poisson/poisson.sh\
+	poisson/res-7.ref\
+	poisson/error.ref\
+	poisson/order.ref\
+	poisson/circle/circle.gfs\
+	poisson/circle/res-7.ref\
+	poisson/circle/error.ref\
+	poisson/circle/order.ref\
+	circle/circle.gfs\
+	circle/circle.sh\
+	circle/res-7.ref\
+	circle/error.ref\
+	circle/order.ref\
+	circle/solution.gfv\
+	circle/refined/refined.gfs\
+	circle/refined/res-7.ref\
+	circle/refined/error.ref\
+	circle/refined/order.ref\
+	circle/refined/solution.gfv\
+	circle/star/star.gfs\
+	circle/star/res-7.ref\
+	circle/star/error.ref\
+	circle/star/order.ref\
+	circle/star/solution.gfv\
+	circle/thin/thin.gfs\
+	circle/thin/res-7.ref\
+	circle/thin/error.ref\
+	circle/thin/order.ref\
+	circle/thin/solution.gfv\
+	dumbell/dumbell.gfs\
+	dumbell/dumbell.sh\
+	advection/advection.gfs\
+	advection/advection.sh\
+	advection/error.ref\
+	advection/order.ref\
+	shear/shear.gfs\
+	shear/shear.sh\
+	shear/norms.ref\
+	shear/curvature/curvature.gfs\
+	shear/curvature/../shear.sh\
+	shear/curvature/norms.ref\
+	shear/curvature/curvature.gfv\
+	reynolds/reynolds.gfs\
+	reynolds/reynolds.sh\
+	reynolds/div5.ref\
+	reynolds/div6.ref\
+	reynolds/div7.ref\
+	reynolds/reynolds.ref\
+	reynolds/box/box.gfs\
+	reynolds/box/../reynolds.sh\
+	reynolds/box/div5.ref\
+	reynolds/box/div6.ref\
+	reynolds/box/div7.ref\
+	reynolds/box/reynolds.ref\
+	periodic/periodic.gfs\
+	periodic/periodic.sh\
+	periodic/r0.ref\
+	periodic/r1.ref\
+	periodic/r2.ref\
+	merging/merging.gfs\
+	merging/merging.sh\
+	merging/levels.gfv\
+	merging/vorticity.gfv\
+	merging/sim.err.ref\
+	merging/simc.err.ref\
+	axi/axi.gfs\
+	axi/axi.sh\
+	axi/error.ref\
+	axi/order.ref\
+	axi/isolines.gfv\
+	axi/viscous/viscous.gfs\
+	axi/viscous/viscous.sh\
+	axi/viscous/cp-12-200\
+	axi/viscous/fadlun\
+	axi/viscous/fadlun-cp-100\
+	axi/viscous/fadlun-cp-200\
+	axi/viscous/Re-12\
+	axi/viscous/zhang\
+	axi/viscous/blanco-1995\
+	axi/viscous/masliyah-1970\
+	axi/viscous/isolines.gfv\
+	axi/viscous/fornberg\
+	axiadvection/axiadvection.gfs\
+	axiadvection/axi.sh\
+	axiadvection/vectors.gfv\
+	axiadvection/vof.gfv\
+	axiadvection/solid/solid.gfs\
+	axiadvection/solid/axi.sh\
+	lid/lid.gfs\
+	lid/lid.sh\
+	lid/xprofile\
+	lid/yprofile\
+	lid/xprof.ghia\
+	lid/yprof.ghia\
+	lid/explicit/explicit.gfs\
+	lid/explicit/lid.sh\
+	poiseuille/poiseuille.gfs\
+	poiseuille/poiseuille.sh\
+	poiseuille/error.ref\
+	couette/couette.gfs\
+	couette/couette.sh\
+	couette/profile\
+	couette/prof-0.ref\
+	couette/prof-1.ref\
+	couette/prof-2.ref\
+	couette/prof-3.ref\
+	kinetic/kinetic.gfs\
+	kinetic/kinetic.gfs\
+	hydrostatic/hydrostatic.gfs\
+	hydrostatic/hydrostatic.gfs\
+	hydrostatic/quadratic/quadratic.gfs\
+	hydrostatic/quadratic/quadratic.gfs\
+	boundaries/boundaries.gfs\
+	boundaries/boundaries.sh\
+	boundaries/orderU.ref\
+	boundaries/orderfU.ref\
+	boundaries/orderV.ref\
+	boundaries/orderfV.ref\
+	channel/channel.gfs\
+	channel/channel.sh\
+	channel/orderU.ref\
+	channel/orderfU.ref\
+	channel/orderV.ref\
+	channel/orderfV.ref\
+	plate/plate.gfs\
+	plate/plate.sh\
+	hexagon/hexagon.gfs\
+	hexagon/hexagon.sh\
+	hexagon/hexagon.gts\
+	hexagon/hexagon.gfv\
+	strouhal/strouhal.gfs\
+	strouhal/strouhal.sh\
+	strouhal/strouhal.gfv\
+	strouhal/strouhal.ref\
+	strouhal/moving.ref\
+	strouhal/static.ref\
+	spurious/spurious.gfs\
+	spurious/spurious.sh\
+	spurious/convergence.ref\
+	spurious/kconvergence.ref\
+	spurious/axi/axi.gfs\
+	spurious/axi/convergence.ref\
+	spurious/axi/kconvergence.ref\
+	capwave/capwave.gfs\
+	capwave/capwave.sh\
+	capwave/convergence.ref\
+	capwave/prosperetti\
+	capwave/markers.tex\
+	capwave/surfer.tex\
+	capwave/prost.tex\
+	capwave/clsvof.tex\
+	capwave/air-water/air-water.gfs\
+	capwave/air-water/convergence.ref\
+	capwave/air-water/prosperetti\
+	capwave/density/density.gfs\
+	capwave/density/convergence.ref\
+	capwave/density/prosperetti\
+	capwave/gravity/gravity.gfs\
+	capwave/gravity/convergence.ref\
+	capwave/gravity/prosperetti\
+	oscillation/oscillation.gfs\
+	oscillation/oscillation.sh\
+	oscillation/fit.ref\
+	geo/geo.gfs\
+	geo/geo.sh\
+	geo/geo.gfv\
+	geo/e.ref\
+	geo/beta/beta.gfs\
+	geo/beta/beta.sh\
+	geo/beta/c\
+	geo/beta/dlw\
+	geo/beta/lls\
+	geo/beta/pzm\
+	geo/beta/llw\
+	geo/beta/energy.ref\
+	geo/beta/energy-nonlinear.ref\
+	waves/waves.gfs\
+	waves/waves.sh\
+	waves/solution.gfv\
+	waves/correlation.ref\
+	waves/adaptive/adaptive.gfs\
+	waves/adaptive/solution.gfv\
+	waves/adaptive/correlation.ref\
+	nz/nz.gfs\
+	nz/nz.gfs\
+	nz/bath.gts\
+	parabola/parabola.gfs\
+	parabola/parabola.sh\
+	parabola/error.ref\
+	parabola/order.ref\
+	lonlat/lonlat.gfs\
+	lonlat/isolines.gfv\
+	lonlat/coriolis/coriolis.gfs\
+	lonlat/coriolis/isolines.gfv\
+	cosine/cosine.gfs\
+	cosine/cosine.sh\
+	cosine/isolines.gfv\
+	cosine/reference.gfv\
+	cosine/zero.gfv\
+	cosine/error-45.ref\
+	cosine/error-90.ref\
+	cosine/rossmanith45\
+	cosine/rossmanith90
+
+EXTRA_DIST += \
+	poisson/poisson.gfs\
+	poisson/poisson.sh\
+	poisson/res-7.ref\
+	poisson/error.ref\
+	poisson/order.ref\
+	poisson/circle/circle.gfs\
+	poisson/circle/res-7.ref\
+	poisson/circle/error.ref\
+	poisson/circle/order.ref\
+	circle/circle.gfs\
+	circle/circle.sh\
+	circle/res-7.ref\
+	circle/error.ref\
+	circle/order.ref\
+	circle/solution.gfv\
+	circle/refined/refined.gfs\
+	circle/refined/res-7.ref\
+	circle/refined/error.ref\
+	circle/refined/order.ref\
+	circle/refined/solution.gfv\
+	circle/star/star.gfs\
+	circle/star/res-7.ref\
+	circle/star/error.ref\
+	circle/star/order.ref\
+	circle/star/solution.gfv\
+	circle/thin/thin.gfs\
+	circle/thin/res-7.ref\
+	circle/thin/error.ref\
+	circle/thin/order.ref\
+	circle/thin/solution.gfv\
+	dumbell/dumbell.gfs\
+	dumbell/dumbell.sh\
+	advection/advection.gfs\
+	advection/advection.sh\
+	advection/error.ref\
+	advection/order.ref\
+	shear/shear.gfs\
+	shear/shear.sh\
+	shear/norms.ref\
+	shear/curvature/curvature.gfs\
+	shear/curvature/../shear.sh\
+	shear/curvature/norms.ref\
+	shear/curvature/curvature.gfv\
+	reynolds/reynolds.gfs\
+	reynolds/reynolds.sh\
+	reynolds/div5.ref\
+	reynolds/div6.ref\
+	reynolds/div7.ref\
+	reynolds/reynolds.ref\
+	reynolds/box/box.gfs\
+	reynolds/box/../reynolds.sh\
+	reynolds/box/div5.ref\
+	reynolds/box/div6.ref\
+	reynolds/box/div7.ref\
+	reynolds/box/reynolds.ref\
+	periodic/periodic.gfs\
+	periodic/periodic.sh\
+	periodic/r0.ref\
+	periodic/r1.ref\
+	periodic/r2.ref\
+	merging/merging.gfs\
+	merging/merging.sh\
+	merging/levels.gfv\
+	merging/vorticity.gfv\
+	merging/sim.err.ref\
+	merging/simc.err.ref\
+	axi/axi.gfs\
+	axi/axi.sh\
+	axi/error.ref\
+	axi/order.ref\
+	axi/isolines.gfv\
+	axi/viscous/viscous.gfs\
+	axi/viscous/viscous.sh\
+	axi/viscous/cp-12-200\
+	axi/viscous/fadlun\
+	axi/viscous/fadlun-cp-100\
+	axi/viscous/fadlun-cp-200\
+	axi/viscous/Re-12\
+	axi/viscous/zhang\
+	axi/viscous/blanco-1995\
+	axi/viscous/masliyah-1970\
+	axi/viscous/isolines.gfv\
+	axi/viscous/fornberg\
+	axiadvection/axiadvection.gfs\
+	axiadvection/axi.sh\
+	axiadvection/vectors.gfv\
+	axiadvection/vof.gfv\
+	axiadvection/solid/solid.gfs\
+	axiadvection/solid/axi.sh\
+	lid/lid.gfs\
+	lid/lid.sh\
+	lid/xprofile\
+	lid/yprofile\
+	lid/xprof.ghia\
+	lid/yprof.ghia\
+	lid/explicit/explicit.gfs\
+	lid/explicit/lid.sh\
+	poiseuille/poiseuille.gfs\
+	poiseuille/poiseuille.sh\
+	poiseuille/error.ref\
+	couette/couette.gfs\
+	couette/couette.sh\
+	couette/profile\
+	couette/prof-0.ref\
+	couette/prof-1.ref\
+	couette/prof-2.ref\
+	couette/prof-3.ref\
+	kinetic/kinetic.gfs\
+	kinetic/kinetic.gfs\
+	hydrostatic/hydrostatic.gfs\
+	hydrostatic/hydrostatic.gfs\
+	hydrostatic/quadratic/quadratic.gfs\
+	hydrostatic/quadratic/quadratic.gfs\
+	boundaries/boundaries.gfs\
+	boundaries/boundaries.sh\
+	boundaries/orderU.ref\
+	boundaries/orderfU.ref\
+	boundaries/orderV.ref\
+	boundaries/orderfV.ref\
+	channel/channel.gfs\
+	channel/channel.sh\
+	channel/orderU.ref\
+	channel/orderfU.ref\
+	channel/orderV.ref\
+	channel/orderfV.ref\
+	plate/plate.gfs\
+	plate/plate.sh\
+	hexagon/hexagon.gfs\
+	hexagon/hexagon.sh\
+	hexagon/hexagon.gts\
+	hexagon/hexagon.gfv\
+	strouhal/strouhal.gfs\
+	strouhal/strouhal.sh\
+	strouhal/strouhal.gfv\
+	strouhal/strouhal.ref\
+	strouhal/moving.ref\
+	strouhal/static.ref\
+	spurious/spurious.gfs\
+	spurious/spurious.sh\
+	spurious/convergence.ref\
+	spurious/kconvergence.ref\
+	spurious/axi/axi.gfs\
+	spurious/axi/convergence.ref\
+	spurious/axi/kconvergence.ref\
+	capwave/capwave.gfs\
+	capwave/capwave.sh\
+	capwave/convergence.ref\
+	capwave/prosperetti\
+	capwave/markers.tex\
+	capwave/surfer.tex\
+	capwave/prost.tex\
+	capwave/clsvof.tex\
+	capwave/air-water/air-water.gfs\
+	capwave/air-water/convergence.ref\
+	capwave/air-water/prosperetti\
+	capwave/density/density.gfs\
+	capwave/density/convergence.ref\
+	capwave/density/prosperetti\
+	capwave/gravity/gravity.gfs\
+	capwave/gravity/convergence.ref\
+	capwave/gravity/prosperetti\
+	oscillation/oscillation.gfs\
+	oscillation/oscillation.sh\
+	oscillation/fit.ref\
+	geo/geo.gfs\
+	geo/geo.sh\
+	geo/geo.gfv\
+	geo/e.ref\
+	geo/beta/beta.gfs\
+	geo/beta/beta.sh\
+	geo/beta/c\
+	geo/beta/dlw\
+	geo/beta/lls\
+	geo/beta/pzm\
+	geo/beta/llw\
+	geo/beta/energy.ref\
+	geo/beta/energy-nonlinear.ref\
+	waves/waves.gfs\
+	waves/waves.sh\
+	waves/solution.gfv\
+	waves/correlation.ref\
+	waves/adaptive/adaptive.gfs\
+	waves/adaptive/solution.gfv\
+	waves/adaptive/correlation.ref\
+	nz/nz.gfs\
+	nz/nz.gfs\
+	nz/bath.gts\
+	parabola/parabola.gfs\
+	parabola/parabola.sh\
+	parabola/error.ref\
+	parabola/order.ref\
+	lonlat/lonlat.gfs\
+	lonlat/isolines.gfv\
+	lonlat/coriolis/coriolis.gfs\
+	lonlat/coriolis/isolines.gfv\
+	cosine/cosine.gfs\
+	cosine/cosine.sh\
+	cosine/isolines.gfv\
+	cosine/reference.gfv\
+	cosine/zero.gfv\
+	cosine/error-45.ref\
+	cosine/error-90.ref\
+	cosine/rossmanith45\
+	cosine/rossmanith90
+
+tests.tex: \
+	poisson/poisson.gfs\
+	poisson/residual.eps\
+	poisson/rate.eps\
+	poisson/error.eps\
+	poisson/order.eps\
+	poisson/circle/circle.gfs\
+	poisson/circle/residual.eps\
+	poisson/circle/rate.eps\
+	poisson/circle/error.eps\
+	poisson/circle/order.eps\
+	circle/circle.gfs\
+	circle/residual.eps\
+	circle/rate.eps\
+	circle/error.eps\
+	circle/order.eps\
+	circle/solution.eps\
+	circle/refined/refined.gfs\
+	circle/refined/residual.eps\
+	circle/refined/rate.eps\
+	circle/refined/error.eps\
+	circle/refined/order.eps\
+	circle/refined/solution.eps\
+	circle/star/star.gfs\
+	circle/star/residual.eps\
+	circle/star/rate.eps\
+	circle/star/error.eps\
+	circle/star/order.eps\
+	circle/star/solution.eps\
+	circle/thin/thin.gfs\
+	circle/thin/residual.eps\
+	circle/thin/rate.eps\
+	circle/thin/error.eps\
+	circle/thin/order.eps\
+	circle/thin/solution.eps\
+	dumbell/dumbell.gfs\
+	advection/advection.gfs\
+	advection/error.eps\
+	advection/order.eps\
+	shear/shear.gfs\
+	shear/t-0.eps\
+	shear/t-2.5.eps\
+	shear/t-5.eps\
+	shear/dt-5.eps\
+	shear/norms\
+	shear/norms.tex\
+	shear/curvature/curvature.gfs\
+	shear/curvature/t-2.5.eps\
+	shear/curvature/dt-5.eps\
+	shear/curvature/norms\
+	shear/curvature/norms.tex\
+	reynolds/reynolds.gfs\
+	reynolds/divmax.eps\
+	reynolds/reynolds.eps\
+	reynolds/divL2.eps\
+	reynolds/kinetic.eps\
+	reynolds/box/box.gfs\
+	reynolds/box/divmax.eps\
+	reynolds/box/reynolds.eps\
+	reynolds/box/divL2.eps\
+	reynolds/box/kinetic.eps\
+	periodic/periodic.gfs\
+	periodic/minion1.tex\
+	merging/merging.gfs\
+	merging/convergence.tex\
+	merging/tv_0_05.eps\
+	merging/tm_0_05.eps\
+	merging/tv_0_15.eps\
+	merging/tm_0_15.eps\
+	merging/tv_0_25.eps\
+	merging/tm_0_25.eps\
+	axi/axi.gfs\
+	axi/error.eps\
+	axi/order.eps\
+	axi/isolines.eps\
+	axi/viscous/viscous.gfs\
+	axi/viscous/length.eps\
+	axi/viscous/Cp.eps\
+	axi/viscous/isolines.eps\
+	axiadvection/axiadvection.gfs\
+	axiadvection/vof.eps\
+	axiadvection/solid/solid.gfs\
+	lid/lid.gfs\
+	lid/xprof\
+	lid/yprof\
+	lid/xprof.eps\
+	lid/yprof.eps\
+	lid/velocity.eps\
+	lid/explicit/explicit.gfs\
+	lid/explicit/xprof\
+	lid/explicit/yprof\
+	lid/explicit/xprof.eps\
+	lid/explicit/yprof.eps\
+	lid/explicit/velocity.eps\
+	poiseuille/poiseuille.gfs\
+	poiseuille/convergence.eps\
+	couette/couette.gfs\
+	couette/prof.eps\
+	kinetic/kinetic.gfs\
+	kinetic/k.eps\
+	hydrostatic/hydrostatic.gfs\
+	hydrostatic/quadratic/quadratic.gfs\
+	boundaries/boundaries.gfs\
+	boundaries/convergence.tex\
+	channel/channel.gfs\
+	channel/convergence.tex\
+	plate/plate.gfs\
+	hexagon/hexagon.gfs\
+	hexagon/error.eps\
+	hexagon/end-2.eps\
+	strouhal/strouhal.gfs\
+	strouhal/strouhal.eps\
+	strouhal/vort.eps\
+	strouhal/forces.eps\
+	spurious/spurious.gfs\
+	spurious/laplace.eps\
+	spurious/curvature.eps\
+	spurious/convergence.eps\
+	spurious/kconvergence.eps\
+	spurious/axi/axi.gfs\
+	spurious/axi/laplace.eps\
+	spurious/axi/curvature.eps\
+	spurious/axi/convergence.eps\
+	spurious/axi/kconvergence.eps\
+	capwave/capwave.gfs\
+	capwave/convergence.tex\
+	capwave/amplitude.eps\
+	capwave/convergence.eps\
+	capwave/markers.tex\
+	capwave/surfer.tex\
+	capwave/prost.tex\
+	capwave/clsvof.tex\
+	capwave/air-water/air-water.gfs\
+	capwave/air-water/convergence.tex\
+	capwave/air-water/amplitude.eps\
+	capwave/density/density.gfs\
+	capwave/density/convergence.tex\
+	capwave/density/amplitude.eps\
+	capwave/gravity/gravity.gfs\
+	capwave/gravity/convergence.tex\
+	capwave/gravity/amplitude.eps\
+	oscillation/oscillation.gfs\
+	oscillation/frequency.eps\
+	oscillation/k.eps\
+	oscillation/laplace.eps\
+	geo/geo.gfs\
+	geo/geo_error.eps\
+	geo/error-100.eps\
+	geo/error-200.eps\
+	geo/error-300.eps\
+	geo/error-400.eps\
+	geo/error-1500.eps\
+	geo/beta/beta.gfs\
+	geo/beta/energy.eps\
+	waves/waves.gfs\
+	waves/correlation\
+	waves/correlation.tex\
+	waves/solution.eps\
+	waves/adaptive/adaptive.gfs\
+	waves/adaptive/correlation\
+	waves/adaptive/correlation.tex\
+	waves/adaptive/solution.eps\
+	nz/nz.gfs\
+	nz/p.eps\
+	nz/k.eps\
+	parabola/parabola.gfs\
+	parabola/elevation.eps\
+	parabola/error.eps\
+	parabola/error-u.eps\
+	parabola/order.eps\
+	parabola/order-u.eps\
+	parabola/u0.eps\
+	lonlat/lonlat.gfs\
+	lonlat/isolines-0.3.eps\
+	lonlat/isolines-0.6.eps\
+	lonlat/isolines-0.9.eps\
+	lonlat/p-0.3.eps\
+	lonlat/p-0.6.eps\
+	lonlat/p-0.9.eps\
+	lonlat/coriolis/coriolis.gfs\
+	lonlat/coriolis/isolines-0.4.eps\
+	lonlat/coriolis/isolines-0.8.eps\
+	lonlat/coriolis/isolines-1.2.eps\
+	cosine/cosine.gfs\
+	cosine/isolines-4-45.eps\
+	cosine/isolines-5-90.eps\
+	cosine/isolines-7-45.eps\
+	cosine/order-90.eps\
+	cosine/isolines-4-90.eps\
+	cosine/isolines-6-45.eps\
+	cosine/isolines-7-90.eps\
+	cosine/isolines-5-45.eps\
+	cosine/isolines-6-90.eps\
+	cosine/order-45.eps
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000..03e8f51
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,564 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = test
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+TESTDIRS = \
+	poisson \
+	circle \
+	dumbell \
+	advection \
+	shear \
+	reynolds \
+	periodic \
+	merging \
+	axi \
+	axiadvection \
+	lid \
+	poiseuille \
+	couette \
+	kinetic \
+	hydrostatic \
+	boundaries \
+	channel \
+	plate \
+	hexagon \
+	strouhal \
+	spurious \
+	capwave \
+	oscillation \
+	geo \
+	waves \
+	nz \
+	parabola \
+	lonlat \
+	cosine
+
+EXTRA_DIST = \
+	template.tex \
+	tests.bib \
+	depend.py \
+	test.py \
+	check.py \
+	gfs2tex \
+	Makefile.deps
+
+TESTS = test.sh
+DOC = tests
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    echo "$$grn$$dashes"; \
+	  else \
+	    echo "$$red$$dashes"; \
+	  fi; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes$$std"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-TESTS check-am clean clean-generic \
+	clean-libtool distclean distclean-generic distclean-libtool \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am
+
+
+test.sh: $(TESTDIRS)
+	@echo "python -u test.py $(TESTDIRS)" > test.sh
+	@chmod +x test.sh
+
+clean-generic:
+	$(RM) *.dvi *.aux *.log *.toc *.out tests.tex *.pyc test.sh *.bbl *.blg Makefile.deps
+
+tests: tests.dvi
+	hevea -fix $(DOC).tex
+	imagen -res 500 -extra "pnmscale 0.24" $(DOC)
+	hacha $(DOC).html
+	rm -f $(DOC).html
+	mv -f $(DOC)[0-9][0-9][0-9].png $(DOC)
+	for f in *.html; do konwert iso1-utf8 < $$f > $(DOC)/$$f; rm -f $$f; done
+	cat $(DOC).css ../doc/share/darcs.css > $(DOC)/$(DOC).css
+	sh ../doc/share/fixnav.sh $(DOC)
+	cp -f ../doc/share/contents.png ../doc/share/next.png ../doc/share/prev.png $(DOC)
+	rm -f *_motif.gif $(DOC).h{tml,aux,ind,toc} $(DOC).image.tex $(DOC).css
+	sh ../doc/examples/crossref.sh --url=http://gfs.sourceforge.net/tests/tests $(TESTDIRS)
+	mv references tests
+
+tests.dvi: tests.tex tests.bib
+	latex -interaction=nonstopmode tests.tex > /dev/null 2>&1
+	bibtex tests
+	latex -interaction=nonstopmode tests.tex > /dev/null 2>&1
+	latex -interaction=nonstopmode tests.tex
+
+tests.pdf: tests.dvi
+	dvips -Ppdf -G0 tests.dvi -o tests.ps
+	ps2pdf -sPAPERSIZE=a4 -dMaxSubsetPct=100 -dCompatibilityLevel=1.2 -dSubsetFonts=true -dEmbedAllFonts=true tests.ps tests.pdf
+	rm -f tests.ps
+
+tests.tex: template.tex Makefile.deps
+	rm -r -f tests
+	python gfs2tex $(TESTDIRS)
+	cp -f template.tex tests.tex
+
+Makefile.deps: Makefile depend.py
+	python depend.py $(TESTDIRS) > Makefile.deps
+
+-include Makefile.deps
+
+tests.tar.gz: tests $(DOCS)
+	tar czf tests.tar.gz tests $(DOCS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/test/advection/advection.gfs b/test/advection/advection.gfs
new file mode 100644
index 0000000..9278a23
--- /dev/null
+++ b/test/advection/advection.gfs
@@ -0,0 +1,55 @@
+# Title: Convergence of the Godunov advection scheme
+#
+# Description:
+#
+# A non-trivial initial tracer distribution is advected by a constant
+# velocity field corresponding to a solid rotation around the center
+# of the domain. The tracer field after one revolution is compared to the
+# initial tracer field to compute the error norms.
+#
+# Figure \ref{error} and \ref{order} illustrate the convergence of the
+# solution with increased resolution. Close to second-order
+# convergence is obtained.
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh advection.sh advection.gfs
+# Version: 091022
+# Required files: advection.sh error.ref order.ref
+# Generated files: error.eps order.eps
+#
+1 0 GfsAdvection GfsBox GfsGEdge {} {
+  Time { end = 0.785398 }
+  Refine LEVEL
+  VariableTracer T { gradient = gfs_center_gradient }
+  Init {} {
+    T = {
+      double r2 = x*x + y*y; 
+      double coeff = 20. + 20000.*r2*r2*r2*r2;
+      return (1. + cos(20.*x)*cos(20.*y))*exp(-coeff*r2)/2.;
+    }
+  }
+  VariableStreamFunction Psi -4.*(x*x + y*y)
+  OutputErrorNorm { start = end } { awk '{ print LEVEL " " $5 " " $7 " " $9}' } { v = T } {
+    s = {
+      double r2 = x*x + y*y; 
+      double coeff = 20. + 20000.*r2*r2*r2*r2;
+      return (1. + cos(20.*x)*cos(20.*y))*exp(-coeff*r2)/2.;
+    }
+  }
+  OutputScalarSum { istep = 1 } t { v = T }
+}
+GfsBox {}
diff --git a/test/advection/advection.sh b/test/advection/advection.sh
new file mode 100644
index 0000000..6873106
--- /dev/null
+++ b/test/advection/advection.sh
@@ -0,0 +1,65 @@
+if ! $donotrun; then
+    rm -f error
+    for level in 4 5 6 7 8; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+	    gerris2D - >> error; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n1[n] = $2; n2[n] = $3; ni[n++] = $4;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n1[i-1]/n1[i])/log(2.) " " log(n2[i-1]/n2[i])/log(2.) " " log(ni[i-1]/ni[i])/log(2.);
+}' < error > order; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'error.eps'
+    set xlabel 'Level'
+    set ylabel 'Error norms'
+    set key
+    set logscale y
+    plot 'error.ref' u 1:2 t '1 (ref)' w lp, \
+         'error.ref' u 1:3 t '2 (ref)' w lp, \
+         'error.ref' u 1:4 t 'max (ref)' w lp, \
+         'error' u 1:2 t '1' w lp, \
+         'error' u 1:3 t '2' w lp, \
+         'error' u 1:4 t 'max' w lp
+    set output 'order.eps'
+    set xlabel 'Level'
+    set ylabel 'Order'
+    set key
+    unset logscale
+    set xtics 0,1
+    set ytics 0,1
+    set grid
+    plot [][0:3] 'order.ref' u 1:2 t '1 (ref)' w lp, \
+                 'order.ref' u 1:3 t '2 (ref)' w lp, \
+                 'order.ref' u 1:4 t 'max (ref)' w lp, \
+                 'order' u 1:2 t '1' w lp, \
+                 'order' u 1:3 t '2' w lp, \
+                 'order' u 1:4 t 'max' w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('error',1,4) - Curve('error.ref',1,4)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/advection/error.ref b/test/advection/error.ref
new file mode 100644
index 0000000..6f0b1da
--- /dev/null
+++ b/test/advection/error.ref
@@ -0,0 +1,5 @@
+4 3.385e-02 6.498e-02 2.842e-01
+5 1.810e-02 3.538e-02 1.643e-01
+6 4.505e-03 8.779e-03 4.327e-02
+7 8.661e-04 1.674e-03 8.888e-03
+8 1.809e-04 3.580e-04 1.916e-03
diff --git a/test/advection/order.ref b/test/advection/order.ref
new file mode 100644
index 0000000..c985201
--- /dev/null
+++ b/test/advection/order.ref
@@ -0,0 +1,4 @@
+5 0.903166 0.877062 0.790574
+6 2.00639 2.01081 1.92489
+7 2.37892 2.39076 2.28344
+8 2.25934 2.22527 2.21376
diff --git a/test/axi/axi.gfs b/test/axi/axi.gfs
new file mode 100644
index 0000000..17d5052
--- /dev/null
+++ b/test/axi/axi.gfs
@@ -0,0 +1,68 @@
+# Title: Potential flow around a sphere
+#
+# Description:
+#
+# The axisymmetric potential flow around a sphere is computed (Figure
+# \ref{isolines}) and compared to the theoretical solution
+# \cite{lamb}. A large domain is used together with variable spatial
+# resolution to minimise the influence of the finite domain size.
+#
+# Figure \ref{error} and \ref{order} illustrate the convergence of the
+# solution for the horizontal component of velocity with increased
+# resolution.
+#
+# \begin{figure}[htbp]
+# \caption{\label{isolines}Isolines of the velocity components ($x$ in red, $y$ in blue).}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{isolines.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh axi.sh axi.gfs
+# Version: 1.3.0
+# Required files: axi.sh error.ref order.ref isolines.gfv
+# Generated files: error.eps order.eps isolines.eps
+#
+1 0 GfsAxi GfsBox GfsGEdge {} {
+    Time { end = 0 }
+    PhysicalParams { L = 50 }
+    AdvectionParams { scheme = none }
+    ApproxProjectionParams { tolerance = 1e-10 }
+    Refine 4
+    Refine (LEVEL + 1./50.*(x*x + y*y)*(4. - LEVEL))
+    Global {
+	#define A0 0.5
+	#define U0 1.
+    }
+    Solid (ellipse (0., 0., A0, A0))
+    Init {} {
+	U = U0
+	Phi = {
+	    double r = sqrt (cx*cx + cy*cy);
+	    return U0*A0*A0*A0*cx/(2.*r*r*r);
+	}
+    }
+    OutputErrorNorm { start = end } { awk '{ print LEVEL " " $7 " " $9}' } { v = U } {
+ 	s = (dx("Phi") + 1.)
+    }
+    OutputSimulation { start = end } sim-LEVEL.gfs
+}
+GfsBox {
+    left = Boundary { BcDirichlet U U0 }
+    right = Boundary { BcDirichlet U U0 }
+}
diff --git a/test/axi/axi.sh b/test/axi/axi.sh
new file mode 100644
index 0000000..11be029
--- /dev/null
+++ b/test/axi/axi.sh
@@ -0,0 +1,66 @@
+if ! $donotrun; then
+    rm -f error
+    for level in 10 11 12 13; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+	    gerris2D - >> error; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if echo "Save isolines.eps { format = EPS }" | gfsview-batch2D sim-13.gfs isolines.gfv; then :
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n2[n] = $2; ni[n++] = $3;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n2[i-1]/n2[i])/log(2.) " " log(ni[i-1]/ni[i])/log(2.);
+}' < error > order; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'error.eps'
+    set xlabel 'Level'
+    set ylabel 'Error norms'
+    set key
+    set logscale y
+    plot 'error.ref' u 1:2 t '2 (ref)' w lp, \
+         'error.ref' u 1:3 t 'max (ref)' w lp, \
+         'error' u 1:2 t '2' w lp, \
+         'error' u 1:3 t 'max' w lp
+    set output 'order.eps'
+    set xlabel 'Level'
+    set ylabel 'Order'
+    set key
+    unset logscale
+    set xtics 0,1
+    set ytics 0,1
+    set grid
+    plot [][0:2] 'order.ref' u 1:2 t '2 (ref)' w lp, \
+                 'order.ref' u 1:3 t 'max (ref)' w lp, \
+                 'order' u 1:2 t '2' w lp, \
+                 'order' u 1:3 t 'max' w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('error',1,3) - Curve('error.ref',1,3)).max() > 1e-5:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/axi/error.ref b/test/axi/error.ref
new file mode 100644
index 0000000..3ce9c93
--- /dev/null
+++ b/test/axi/error.ref
@@ -0,0 +1,4 @@
+10 1.102e-04 1.210e-01
+11 3.994e-05 5.267e-02
+12 1.418e-05 2.793e-02
+13 5.068e-06 1.466e-02
diff --git a/test/axi/isolines.gfv b/test/axi/isolines.gfv
new file mode 100644
index 0000000..8051ad4
--- /dev/null
+++ b/test/axi/isolines.gfv
@@ -0,0 +1,58 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 0.955076
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 1 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} U {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 10
+}
+Isoline {
+  r = 0 g = 0.0160678 b = 1
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} V {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 10
+}
+Symmetry {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 1 n.z = 0
+  pos = 0
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
diff --git a/test/axi/order.ref b/test/axi/order.ref
new file mode 100644
index 0000000..273bbb2
--- /dev/null
+++ b/test/axi/order.ref
@@ -0,0 +1,3 @@
+11 1.46422 1.19995
+12 1.49398 0.915166
+13 1.48437 0.92993
diff --git a/test/axi/viscous/Re-12 b/test/axi/viscous/Re-12
new file mode 100644
index 0000000..4094da1
--- /dev/null
+++ b/test/axi/viscous/Re-12
@@ -0,0 +1,12 @@
+20 100 0.00601338 0.00214903
+30 100 0.144321 -1.54293e-05
+40 100 0.281624 0.000964816
+50 100 0.405324 2.30829e-05
+60 100 0.51502 2.97476e-05
+80 22.7 0.703601 0.000283994
+100 28.1 0.86826 -0.00022001
+120 31.4 1.01188 -1.2337e-05
+150 31.5 1.19646 -6.03988e-05
+200 36.2 1.44074 -6.93522e-05
+250 76 1.62679 -2.93692e-06
+300 100 1.76844 -1.06835e-07
diff --git a/test/axi/viscous/blanco-1995 b/test/axi/viscous/blanco-1995
new file mode 100644
index 0000000..d341ff4
--- /dev/null
+++ b/test/axi/viscous/blanco-1995
@@ -0,0 +1,4 @@
+20.0453 0
+38.4509 0.46092
+70.6662 1.22222
+99.8764 1.72006
diff --git a/test/axi/viscous/cp-12-200 b/test/axi/viscous/cp-12-200
new file mode 100644
index 0000000..e173896
--- /dev/null
+++ b/test/axi/viscous/cp-12-200
@@ -0,0 +1,162 @@
+0.0122082 1.03596
+0.036632 1.03337
+0.0610778 1.02801
+0.08556 1.01973
+0.110094 1.00848
+0.134694 0.994156
+0.159377 0.97694
+0.184158 0.963758
+0.206752 0.95857
+0.219232 0.956152
+0.234084 0.941808
+0.259263 0.90893
+0.284612 0.879878
+0.303968 0.867636
+0.316787 0.86038
+0.335899 0.834982
+0.361881 0.79477
+0.378716 0.777
+0.391904 0.765906
+0.414648 0.733718
+0.435666 0.70047
+0.449168 0.686672
+0.468673 0.657964
+0.489793 0.621894
+0.503675 0.60358
+0.52422 0.569548
+0.542272 0.533592
+0.556615 0.51391
+0.579278 0.479456
+0.593887 0.455112
+0.611131 0.426434
+0.630019 0.387948
+0.645253 0.36276
+0.665318 0.328058
+0.680918 0.298664
+0.700022 0.264834
+0.716033 0.235808
+0.734326 0.203932
+0.7508 0.174536
+0.768399 0.143297
+0.785398 0.113224
+0.802397 0.0835276
+0.819997 0.0534478
+0.83647 0.0237254
+0.854763 -0.00820992
+0.870775 -0.0372544
+0.889878 -0.0703106
+0.905479 -0.0983104
+0.925544 -0.129695
+0.940778 -0.150842
+0.959665 -0.183019
+0.976909 -0.207078
+0.991519 -0.230668
+1.01418 -0.26238
+1.02852 -0.278202
+1.04658 -0.308696
+1.06712 -0.337024
+1.081 -0.351164
+1.10212 -0.378892
+1.12163 -0.399754
+1.13513 -0.40825
+1.15615 -0.4347
+1.17889 -0.458974
+1.19208 -0.46304
+1.20891 -0.470916
+1.2349 -0.50155
+1.25401 -0.519646
+1.26683 -0.51963
+1.28618 -0.519728
+1.31153 -0.537734
+1.33671 -0.561508
+1.35156 -0.56906
+1.36404 -0.564762
+1.38664 -0.555342
+1.41142 -0.554992
+1.4361 -0.561374
+1.4607 -0.564578
+1.48524 -0.565088
+1.50972 -0.563096
+1.53416 -0.558486
+1.55859 -0.551548
+1.583 -0.542996
+1.60743 -0.533548
+1.63187 -0.523638
+1.65636 -0.513396
+1.68089 -0.502784
+1.70549 -0.49173
+1.73017 -0.480044
+1.75495 -0.46499
+1.77755 -0.450128
+1.79003 -0.443966
+1.80488 -0.437696
+1.83006 -0.427432
+1.85541 -0.414374
+1.87476 -0.40278
+1.88758 -0.396722
+1.90669 -0.388444
+1.93268 -0.376222
+1.94951 -0.367008
+1.9627 -0.36128
+1.98544 -0.351782
+2.00646 -0.342482
+2.01996 -0.337486
+2.03947 -0.329846
+2.06059 -0.320994
+2.07447 -0.316432
+2.09502 -0.309344
+2.11307 -0.302192
+2.12741 -0.297794
+2.15007 -0.291136
+2.16468 -0.287044
+2.18193 -0.28244
+2.20081 -0.276632
+2.21605 -0.272968
+2.23611 -0.268362
+2.25171 -0.264858
+2.27082 -0.260936
+2.28683 -0.25778
+2.30512 -0.254544
+2.3216 -0.251754
+2.3392 -0.249158
+2.35619 -0.246772
+2.37319 -0.2446
+2.39079 -0.242494
+2.40727 -0.24068
+2.42556 -0.238842
+2.44157 -0.23724
+2.46067 -0.235464
+2.47627 -0.233902
+2.49634 -0.232184
+2.51157 -0.231044
+2.53046 -0.229146
+2.54771 -0.22774
+2.56232 -0.226114
+2.58498 -0.22391
+2.59932 -0.222744
+2.61737 -0.21986
+2.63792 -0.217012
+2.6518 -0.21531
+2.67292 -0.211322
+2.69242 -0.208046
+2.70593 -0.206326
+2.72694 -0.20112
+2.74969 -0.196002
+2.76288 -0.194366
+2.77971 -0.191118
+2.80569 -0.18289
+2.82481 -0.177534
+2.83762 -0.176016
+2.85698 -0.173063
+2.88233 -0.165418
+2.90751 -0.156343
+2.92236 -0.152274
+2.93484 -0.151542
+2.95743 -0.14985
+2.98222 -0.14547
+3.0069 -0.139639
+3.0315 -0.134555
+3.05603 -0.130407
+3.08051 -0.127268
+3.10496 -0.125194
+3.12938 -0.124181
diff --git a/test/axi/viscous/fadlun b/test/axi/viscous/fadlun
new file mode 100644
index 0000000..7d3dee7
--- /dev/null
+++ b/test/axi/viscous/fadlun
@@ -0,0 +1,10 @@
+#x Fadlun
+25.1277 0.0820564
+30.2905 0.141539
+39.8675 0.297622
+50.1931 0.416587
+59.7792 0.535541
+75.2714 0.699138
+79.7001 0.736332
+199.284 1.70345
+498.74 2.10889
diff --git a/test/axi/viscous/fadlun-cp-100 b/test/axi/viscous/fadlun-cp-100
new file mode 100644
index 0000000..738f6e7
--- /dev/null
+++ b/test/axi/viscous/fadlun-cp-100
@@ -0,0 +1,100 @@
+0.00650221 1.09141
+0.0402099 1.09138
+0.0708118 1.08118
+0.101414 1.07099
+0.138103 1.05063
+0.177828 1.0235
+0.226719 0.989586
+0.269482 0.955678
+0.30606 0.908232
+0.345717 0.86417
+0.379286 0.830272
+0.421938 0.769275
+0.440213 0.742167
+0.470691 0.7015
+0.49809 0.657451
+0.516365 0.630343
+0.531576 0.603237
+0.549851 0.576129
+0.726338 0.271189
+0.741535 0.240698
+0.750631 0.216986
+0.768907 0.189877
+0.784118 0.162772
+0.802393 0.135663
+0.81759 0.105172
+0.835865 0.0780634
+0.893687 -0.020196
+0.951522 -0.115069
+0.969797 -0.142178
+0.988072 -0.169287
+1.00328 -0.196392
+1.02464 -0.220118
+1.06726 -0.287886
+1.1069 -0.335335
+1.12826 -0.359061
+1.20452 -0.443797
+1.22895 -0.464141
+1.25033 -0.481095
+1.29918 -0.525168
+1.32672 -0.535357
+1.35426 -0.545547
+1.3787 -0.562504
+1.40933 -0.565925
+1.43073 -0.579493
+1.45214 -0.589675
+1.46744 -0.593078
+1.49807 -0.596499
+1.51034 -0.593127
+1.541 -0.589775
+1.56553 -0.586417
+1.59616 -0.589838
+1.62072 -0.579707
+1.65135 -0.583128
+1.67895 -0.576387
+1.70659 -0.562874
+1.73727 -0.552751
+1.74648 -0.549375
+1.77409 -0.542634
+1.80172 -0.529122
+1.86004 -0.505485
+1.90917 -0.481839
+1.9368 -0.468326
+1.95831 -0.454806
+1.98286 -0.444676
+2.00742 -0.434546
+2.03197 -0.424415
+2.05347 -0.414282
+2.0811 -0.400769
+2.10872 -0.390642
+2.13635 -0.377129
+2.16705 -0.36362
+2.19466 -0.356879
+2.22229 -0.343366
+2.24684 -0.336622
+2.27752 -0.326498
+2.30514 -0.316371
+2.33276 -0.306245
+2.36037 -0.299504
+2.38799 -0.289377
+2.41866 -0.28264
+2.4432 -0.275895
+2.47387 -0.269158
+2.50148 -0.262417
+2.53215 -0.25568
+2.55976 -0.248939
+2.5843 -0.242194
+2.61189 -0.23884
+2.75911 -0.208532
+2.78669 -0.208563
+2.81429 -0.201822
+2.84495 -0.198471
+2.87562 -0.191733
+2.90628 -0.188382
+2.93387 -0.185027
+2.96453 -0.181676
+2.99519 -0.178324
+3.02279 -0.171583
+3.05342 -0.175004
+3.08408 -0.171652
+3.11474 -0.168301
diff --git a/test/axi/viscous/fadlun-cp-200 b/test/axi/viscous/fadlun-cp-200
new file mode 100644
index 0000000..f4f317d
--- /dev/null
+++ b/test/axi/viscous/fadlun-cp-200
@@ -0,0 +1,100 @@
+#x Re-200
+0.00933136 1.03385
+0.0368966 1.03043
+0.0675123 1.02363
+0.0950636 1.01682
+0.122615 1.01002
+0.150139 0.996445
+0.174584 0.979487
+0.19903 0.962529
+0.220397 0.942189
+0.247907 0.925228
+0.26926 0.901502
+0.290628 0.881162
+0.311981 0.857436
+0.333335 0.83371
+0.354688 0.809983
+0.406505 0.742205
+0.497882 0.606662
+0.577015 0.474518
+0.637859 0.366097
+0.713901 0.227185
+0.774772 0.125536
+0.823484 0.0476033
+0.838681 0.0171121
+0.856956 -0.00999656
+0.872167 -0.0371018
+0.890442 -0.0642104
+0.908718 -0.0913191
+0.923929 -0.118424
+0.942204 -0.145533
+0.96048 -0.172642
+1.10064 -0.369188
+1.12199 -0.392914
+1.14336 -0.413254
+1.16471 -0.43698
+1.18609 -0.453935
+1.20746 -0.474275
+1.25941 -0.508193
+1.3175 -0.542119
+1.37565 -0.559115
+1.4308 -0.562563
+1.45838 -0.562594
+1.48902 -0.562629
+1.51664 -0.552502
+1.54425 -0.545761
+1.57185 -0.53902
+1.5964 -0.532276
+1.62709 -0.518766
+1.65775 -0.515415
+1.69768 -0.491758
+1.72532 -0.478245
+1.75297 -0.461346
+1.78059 -0.45122
+1.8236 -0.42418
+1.85122 -0.414053
+1.8758 -0.397151
+1.90344 -0.383638
+1.92799 -0.373508
+1.95563 -0.359995
+1.98326 -0.346482
+2.01088 -0.336355
+2.03547 -0.319453
+2.06614 -0.312716
+2.09376 -0.302589
+2.12443 -0.295852
+2.14899 -0.285721
+2.17967 -0.275598
+2.21034 -0.26886
+2.23795 -0.26212
+2.26862 -0.255382
+2.29621 -0.252027
+2.32687 -0.248676
+2.35448 -0.241935
+2.38513 -0.238584
+2.41273 -0.235229
+2.44032 -0.231874
+2.47096 -0.231909
+2.50162 -0.228557
+2.53226 -0.228592
+2.55987 -0.221851
+2.59053 -0.218499
+2.63344 -0.215162
+2.68863 -0.208452
+2.73156 -0.201729
+2.75918 -0.191602
+2.78983 -0.18825
+2.81744 -0.18151
+2.84813 -0.171386
+2.87572 -0.168031
+2.9064 -0.157908
+2.9156 -0.157918
+2.9432 -0.151177
+2.97387 -0.14444
+3.00454 -0.137703
+3.03214 -0.134348
+3.05973 -0.130993
+3.09039 -0.127642
+3.12104 -0.12429
+
+
diff --git a/test/axi/viscous/fornberg b/test/axi/viscous/fornberg
new file mode 100644
index 0000000..6d08956
--- /dev/null
+++ b/test/axi/viscous/fornberg
@@ -0,0 +1,6 @@
+#x Fornberg
+99.6247 0.922272
+199.31 1.59949
+497.977 2.20542
+
+
diff --git a/test/axi/viscous/isolines.gfv b/test/axi/viscous/isolines.gfv
new file mode 100644
index 0000000..02d6561
--- /dev/null
+++ b/test/axi/viscous/isolines.gfv
@@ -0,0 +1,75 @@
+# GfsView 2D
+View {
+  tx = -0.0102258 ty = 2.77268e-05
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 0.895771
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 1 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} U {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 10
+}
+Isoline {
+  r = 0 g = 0.0160678 b = 1
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} V {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 10
+}
+Isoline {
+  r = 0 g = 0.803098 b = 0.139818
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} U {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 0 levels = 0
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Symmetry {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 1 n.z = 0
+  pos = 0
+}
diff --git a/test/axi/viscous/masliyah-1970 b/test/axi/viscous/masliyah-1970
new file mode 100644
index 0000000..9fa5f84
--- /dev/null
+++ b/test/axi/viscous/masliyah-1970
@@ -0,0 +1,5 @@
+20.0094 0.0825769
+49.99 0.91264
+99.9148 1.6556
+
+
diff --git a/test/axi/viscous/viscous.gfs b/test/axi/viscous/viscous.gfs
new file mode 100644
index 0000000..10fc40c
--- /dev/null
+++ b/test/axi/viscous/viscous.gfs
@@ -0,0 +1,101 @@
+# Title: Viscous flow past a sphere
+#
+# Description:
+#
+# When viscosity is added, a recirculation region develops behind the
+# sphere (Figure \ref{isolines}). 
+#
+# \begin{figure}[htbp]
+# \caption{\label{isolines}Viscous flow around a sphere at Reynolds
+# 100. Isolines of the velocity components ($x$ in red, $y$ in
+# blue). The recirculation region is indicated by the green isoline
+# where the value of the horizontal velocity component vanishes.}
+# \begin{center}
+# \includegraphics[width=\hsize]{isolines.eps}
+# \end{center}
+# \end{figure}
+#
+# The length of the recirculation depends on the Reynolds
+# number. Figure \ref{length} plots the results obtained with Gerris
+# as well as previously published results. Published results agree
+# with Gerris for Reynolds numbers smaller than 100. The mismatch for
+# results at Reynolds 200 can be attributed to the coarse mesh used to
+# resolve the wake in the studies of Fornberg \cite{fornberg1988} and
+# Fadlun et al \cite{fadlun2000}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{length}Relative length of the recirculation region
+# as a function of the Reynolds number. The results of Gerris are
+# compared with the results of Masliyah \& Epstein
+# \cite{masliyah1970}, Fornberg \cite{fornberg1988}, Blanco \&
+# Magnaudet \cite{blanco1995}, Fadlun et al \cite{fadlun2000} and
+# Zhang \& Zheng \cite{zhang2007}.}
+# \begin{center}
+# \includegraphics[width=\hsize]{length.eps}
+# \end{center}
+# \end{figure}
+#
+# The pressure profiles are also in good agreement with those reported
+# by Fadlun et al (which also agree with those of Fornberg) (Figure
+# \ref{Cp}).
+#
+# \begin{figure}[htbp]
+# \caption{\label{Cp}Pressure coefficient over the sphere surface at
+# Reynolds numbers 100 and 200.}
+# \begin{center}
+# \includegraphics[width=\hsize]{Cp.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh viscous.sh
+# Version: 1.3.0
+# Required files: viscous.sh cp-12-200 fadlun fadlun-cp-100 fadlun-cp-200 Re-12 zhang blanco-1995 masliyah-1970 isolines.gfv fornberg
+# Generated files: length.eps Cp.eps isolines.eps
+#
+
+Define A0 0.5
+Define U0 1.
+
+1 0 GfsAxi GfsBox GfsGEdge {} {
+    Time { end = 100 }
+    PhysicalParams { L = 50 }
+    AdvectionParams { gc = 1 }
+    Refine 4
+    Refine (LEVEL + 1./50.*(x*x + y*y)*(4. - LEVEL))
+    Solid (ellipse (0., 0., A0, A0))
+    SourceViscosity 1./RE
+    Init {} { U = U0 }
+    AdaptGradient { istep = 1 } { cmax = 5e-2 maxlevel = LEVEL } U
+    AdaptGradient { istep = 1 } { cmax = 5e-2 maxlevel = LEVEL } V
+    AdaptFunction { istep = 1 } { cmax = 1e-2 maxlevel = LEVEL } {
+	return (fabs(dx("U"))+fabs(dy("U")))/fabs(U)*ftt_cell_size (cell);
+    }
+    EventStop { step = 0.1 } U 1e-3 DU
+
+#    OutputTime { step = 1 } stderr
+#    OutputScalarNorm { step = 1 } stderr { v = DU }
+    OutputSimulation { start = end } end-LEVEL-RE.gfs
+    OutputLocation { step = 0.1 } {
+	awk 'BEGIN { t = 2.; oldl = -1.; oldt = 0.; } {
+          if ($1 != t) { t = $1; x1 = $2; u1 = $7; }
+          else {
+            x2 = $2; u2 = $7;
+            if (u1 <= 0. && u2 > 0.) {
+              l = (u1*x2 - u2*x1)/(u1 - u2) - A0;
+              dl = (l - oldl)/(t - oldt);
+              print t, l, dl;
+              fflush (stdout);
+              oldl = l;
+              oldt = t;
+            }
+            x1 = x2; u1 = u2;
+          }
+        }' > l-LEVEL-RE
+    } axis
+}
+GfsBox {
+    left = Boundary { BcDirichlet U U0 }
+    right = BoundaryOutflow
+    bottom = Boundary
+}
diff --git a/test/axi/viscous/viscous.sh b/test/axi/viscous/viscous.sh
new file mode 100644
index 0000000..6d96e31
--- /dev/null
+++ b/test/axi/viscous/viscous.sh
@@ -0,0 +1,50 @@
+if ! $donotrun; then
+    awk 'BEGIN{ for (x = 0.5; x <= 3.; x += 1./256.) print x, 0., 0.;}' > axis
+    for Re in 100; do
+	if gerris2D -DLEVEL=12 -DRE=$Re viscous.gfs; then :
+	else
+	    exit 1
+	fi
+	if gfs2oogl2D -c P -o -i < end-12-$Re.gfs | \
+	    awk '{print 3.14159265359 - atan2($2,$1),$4*2.}' | \
+	    sort -k 1,2 > cp-12-$Re; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if echo "Save isolines.eps { format = EPS }" | gfsview-batch2D  end-12-100.gfs isolines.gfv; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+set term postscript eps color lw 3 solid 20
+set key bottom right
+set pointsize 1.5
+set output 'length.eps'
+set xlabel 'Reynolds number'
+set ylabel 'Recirculation length'
+plot [0:320][0:]'fadlun' t 'Fadlun et al. (2000)', 'fornberg' t 'Fornberg (1988)', 'zhang' t 'Zhang & Zheng (2007)' pt 2, 'blanco-1995' u 1:(\$2/2.) t 'Blanco & Magnaudet (1995)', 'masliyah-1970' u 1:(\$2/2.) t 'Masliyah & Epstein (1970)' pt 8 lt 7, 'Re-12' u 1:3 smooth csplines w l t '' lt 5, 'Re-12' u 1:3 t 'Gerris' lt 5 pt 1
+
+set key top right
+set xlabel 'Angle'
+set ylabel 'Cp'
+set output 'Cp.eps'
+plot 'fadlun-cp-100' u (\$1*180./pi):2 w l t 'Fadlun et al., Re = 100', 'cp-12-100' u (\$1*180./pi):2 w l t 'Gerris, Re = 100', 'fadlun-cp-200' u (\$1*180./pi):2 w l t 'Fadlun et al., Re = 200', 'cp-12-200' u (\$1*180./pi):2 w l t 'Gerris, Re = 200'
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('cp-12-100',1,2) - Curve('fadlun-cp-100',1,2)).norm2() > 1e-2:
+    print (Curve('cp-12-100',1,2) - Curve('fadlun-cp-100',1,2)).norm2()
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/axi/viscous/zhang b/test/axi/viscous/zhang
new file mode 100644
index 0000000..b9f8bb9
--- /dev/null
+++ b/test/axi/viscous/zhang
@@ -0,0 +1,9 @@
+#x Zhang
+29.8903 0.133929
+40.0366 0.262897
+49.9086 0.386905
+60.0548 0.491071
+80.0731 0.674603
+99.8172 0.848214
+
+
diff --git a/test/axiadvection/axi.sh b/test/axiadvection/axi.sh
new file mode 100644
index 0000000..771af68
--- /dev/null
+++ b/test/axiadvection/axi.sh
@@ -0,0 +1,47 @@
+if ! $donotrun; then
+    gerris2D axiadvection.gfs | gfsview-batch2D -s vof.gfv > vof.gnu
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'vof.eps'
+    set xlabel 'z'
+    set ylabel 'r'
+    unset key
+    set xtics -0.5,.25,0.5
+    set size ratio -1
+    plot [-0.5:0.5][0:1]'vof.gnu' u 1:2 w l, 'vectors.gnu' u 1:2 w l
+EOF
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { min = 1000.; max = -1000.; }{ 
+  if ($5 < min) min = $5; 
+  if ($5 > max) max = $5; 
+}
+END {
+  e = 2.*(max - min)/(max + min);
+  print "VOF:", e;
+  if (e > 4e-4)
+    exit (1);
+}' < srt; then :
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { min = 1000.; max = -1000.; }{ 
+  if ($5 < min) min = $5; 
+  if ($5 > max) max = $5; 
+}
+END {
+  e = 2.*(max - min)/(max + min);
+  print "Standard:", e;
+  if (e > 1.5e-7)
+    exit (1);
+}' < srt1; then :
+else
+    exit 1
+fi
diff --git a/test/axiadvection/axiadvection.gfs b/test/axiadvection/axiadvection.gfs
new file mode 100644
index 0000000..ed25c0c
--- /dev/null
+++ b/test/axiadvection/axiadvection.gfs
@@ -0,0 +1,53 @@
+# Title: Mass conservation
+#
+# Description:
+#
+# A standard and a VOF tracer are advected by an axisymmetric
+# flow. The initial interface is a torus which is then advected by the
+# flow illustrated in Figure \ref{vof}. As the torus is flattened
+# against the right-hand-side wall, its cross-sectional surface area
+# decreases but the volume should remain constant. This is indeed the
+# case to within 0.04\% for the VOF tracer and $1.5\times 10^{-5}$\% for
+# the standard tracer.
+#
+# \begin{figure}[htbp]
+# \caption{\label{vof}VOF interface (red) and velocity field (green).}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{vof.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh axi.sh
+# Version: 1.3.0
+# Required files: axi.sh vectors.gfv vof.gfv
+# Generated files: vof.eps
+#
+1 0 GfsAxi GfsBox GfsGEdge {} {
+    Time { end = 1.3 }
+    Refine 6
+    Init {} { U = 1 }
+    VariableTracerVOF T
+    VariableTracer T1
+    InitFraction T (- ellipse (0, 0.3, 0.1, 0.1))
+    InitFraction T1 (- ellipse (0, 0.3, 0.1, 0.1))
+    AdaptGradient { istep = 1 } { cmax = 1e-3 minlevel = 4 maxlevel = (x < 0.25 ? 6 : 7) } T1
+    OutputScalarSum { istep = 1 end = 0.8 } srt { v = T }
+    OutputScalarSum { istep = 1 end = 0.8 } srt1 { v = T1 }
+    OutputSimulation { step = 0.2 } stdout
+    EventScript { step = 0.2 } {
+	echo "Save stdout { format = Gnuplot }"
+    }
+    EventScript { start = 1.2 } {
+	echo "Clear"
+	cat vectors.gfv
+	echo "Save vectors.gnu { format = Gnuplot }"
+    }
+}
+GfsBox {
+    left = Boundary {
+	BcDirichlet U 1
+	BcDirichlet V 0
+    }
+    top = BoundaryOutflow
+}
diff --git a/test/axiadvection/solid/axi.sh b/test/axiadvection/solid/axi.sh
new file mode 100644
index 0000000..d4f967b
--- /dev/null
+++ b/test/axiadvection/solid/axi.sh
@@ -0,0 +1,33 @@
+if ! $donotrun; then
+    gerris2D solid.gfs
+fi
+
+if awk '
+BEGIN { min = 1000.; max = -1000.; }{ 
+  if ($5 < min) min = $5; 
+  if ($5 > max) max = $5; 
+}
+END {
+  e = 2.*(max - min)/(max + min);
+  print "VOF:", e;
+  if (e > 2.5e-2)
+    exit (1);
+}' < srt; then :
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { min = 1000.; max = -1000.; }{ 
+  if ($5 < min) min = $5; 
+  if ($5 > max) max = $5; 
+}
+END {
+  e = 2.*(max - min)/(max + min);
+  print "Standard:", e;
+  if (e > 0.)
+    exit (1);
+}' < srt1; then :
+else
+    exit 1
+fi
diff --git a/test/axiadvection/solid/solid.gfs b/test/axiadvection/solid/solid.gfs
new file mode 100644
index 0000000..fa29083
--- /dev/null
+++ b/test/axiadvection/solid/solid.gfs
@@ -0,0 +1,33 @@
+# Title: Mass conservation with solid boundary
+#
+# Description:
+#
+# A similar test but for tracers advected around a solid sphere.
+#
+# Author: St\'ephane Popinet
+# Command: sh axi.sh
+# Version: 1.3.0
+# Required files: axi.sh
+#
+1 0 GfsAxi GfsBox GfsGEdge {} {
+    Time { end = 0.55 }
+    Refine (x < 0. ? 7 : 8)
+    Init {} { U = 1 }
+    ApproxProjectionParams { tolerance = 1e-6 }
+    ProjectionParams { tolerance = 1e-6 }
+    Solid (ellipse (0., 0., 0.05, 0.05))
+    VariableTracerVOF T
+    VariableTracer T1
+    InitFraction T (- ellipse (-0.2, 0., 0.05, 0.05))
+    InitFraction T1 (- ellipse (-0.2, 0., 0.05, 0.05))
+    AdaptGradient { istep = 1 } { cmax = 1e-3 minlevel = 4 maxlevel = (x < 0. ? 7 : 8) } T1
+    OutputScalarSum { istep = 1 } srt { v = T }
+    OutputScalarSum { istep = 1 } srt1 { v = T1 }
+}
+GfsBox {
+    left = Boundary {
+	BcDirichlet U 1
+	BcDirichlet V 0
+    }
+    right = BoundaryOutflow
+}
diff --git a/test/axiadvection/vectors.gfv b/test/axiadvection/vectors.gfv
new file mode 100644
index 0000000..bc7eb47
--- /dev/null
+++ b/test/axiadvection/vectors.gfv
@@ -0,0 +1,26 @@
+# GfsView 2D
+View {
+  tx = -0.0177224 ty = -0.490634
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 22.0083
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Vectors {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = 4
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} U V {
+  scale = 0.07499
+  use_scalar = 0
+}
diff --git a/test/axiadvection/vof.gfv b/test/axiadvection/vof.gfv
new file mode 100644
index 0000000..1cb7f74
--- /dev/null
+++ b/test/axiadvection/vof.gfv
@@ -0,0 +1,27 @@
+# GfsView 2D
+View {
+  tx = -0.0177224 ty = -0.490634
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 22.0083
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+VOF {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} T {
+  reversed = 0
+  use_scalar = 0
+  draw_edges = 0
+}
diff --git a/test/boundaries/boundaries.gfs b/test/boundaries/boundaries.gfs
new file mode 100644
index 0000000..1d68647
--- /dev/null
+++ b/test/boundaries/boundaries.gfs
@@ -0,0 +1,48 @@
+# Title: Convergence of a potential flow solution
+#
+# Description:
+#
+# A test case initially presented by Almgren et al \cite{almgren97}.
+# Three elliptical bodies are placed in the unit square. Constant
+# unity inflow and outflow are specified on the left and right
+# boundaries. Projection is then performed to obtain a potential flow
+# solution around the bodies.
+#
+# Tables \ref{boundaries-x} and \ref{boundaries-y} illustrate the errors and convergence
+# orders obtained for both components of the velocity when the
+# resolution varies. Richardson extrapolation is used.  The errors are
+# computed either on the whole domain (All cells) or on the cells
+# whose parents at level 7 are entirely contained in the fluid (Full
+# 128 cells).
+#
+# Close to second-order convergence is obtained in the bulk of the
+# fluid, reducing to first-order close to the boundaries. The errors
+# are small in all cases (with a maximum of 6\%) and comparable to
+# that obtained by Almgren et al using a different discretisation.
+#
+# \input{convergence.tex}
+#
+# Author: St\'ephane Popinet
+# Command: sh boundaries.sh boundaries.gfs
+# Version: 0.6.4
+# Required files: boundaries.sh orderU.ref orderfU.ref orderV.ref orderfV.ref
+# Running time: 3 minutes
+# Generated files: convergence.tex
+#
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Time { iend = 0 end = 1 }
+    AdvectionParams { scheme = none }
+    ApproxProjectionParams { tolerance = 1e-6 }
+    Refine LEVEL
+    Solid (ellipse (0.25, 0.25, 0.1, 0.1))
+    Solid (ellipse (-0.25, 0.125, 0.15, 0.1))
+    Solid (ellipse (0., -0.25, 0.2, 0.1))
+    Init {} { U = 1 }
+    OutputSimulation { start = end } sim-LEVEL {
+        variables = U,V,P
+    }
+}
+GfsBox {
+    left = Boundary { BcDirichlet U 1 }
+    right = Boundary { BcDirichlet U 1 }
+}
diff --git a/test/boundaries/boundaries.sh b/test/boundaries/boundaries.sh
new file mode 100644
index 0000000..e87c5f2
--- /dev/null
+++ b/test/boundaries/boundaries.sh
@@ -0,0 +1,82 @@
+if ! $donotrun; then
+    for level in 7 8 9; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+           gerris2D -; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+for v in U V; do
+    rm -f order$v orderf$v
+    for level in 7 8; do
+	level1=`expr $level + 1`
+	echo -n "$level " >> order$v
+	if gfscompare2D -v sim-$level sim-$level1 $v 2>&1 | \
+	    awk '{if ($1 == "total") print $4 " " $6 " " $8;}' >> order$v; then :
+	else
+	    exit 1
+	fi
+	echo -n "$level " >> orderf$v
+	if gfscompare2D -f 7 -v sim-$level sim-$level1 $v 2>&1 | \
+	    awk '{if ($1 == "total") print $4 " " $6 " " $8;}' >> orderf$v; then :
+	else
+	    exit 1
+	fi
+    done
+done
+
+if cat <<EOF | python > convergence.tex; then :
+from check import *
+from sys import *
+from math import *
+
+for component,variable in [('x','U'),('y','V')]:
+  print r"""\begin{table}[htbp]
+  \caption{"""
+  print r"\label{boundaries-" + component + "}"
+  print r"Errors and convergence rates for the \$"+component+r"\$-component of the velocity.}"  
+  print r"""\begin{center}
+  \begin{tabular}{||l|c|c|c||c|c|c||} \hline
+           & \multicolumn{3}{c||}{All cells} & \multicolumn{3}{c||}{Full 128 cells} \\\ \hline
+           & 128-256  & Rate & 256-512  & 128-256  & Rate & 256-512  \\\ \hline"""
+
+  for i,name in [(2,r"\$L_1\$"),(3,r"\$L_2\$"),(4,r"\$L_\infty\$")]:
+    a=Curve('order'+variable,1,i)
+    b=Curve('orderf'+variable,1,i)
+    print name,
+    print "& %.2e & %4.2f & %.2e & %.2e & %4.2f & %.2e" % (\
+    a.l[0][1], log(a.l[0][1]/a.l[1][1])/log(2.), a.l[1][1], \
+    b.l[0][1], log(b.l[0][1]/b.l[1][1])/log(2.), b.l[1][1]),
+    print r"\\\"
+
+    a=Curve('order'+variable+'.ref',1,i)
+    b=Curve('orderf'+variable+'.ref',1,i)
+    print "& {\color{blue}%.2e} & {\color{blue}%4.2f} & {\color{blue}%.2e} & {\color{blue}%.2e} & {\color{blue}%4.2f} & {\color{blue}%.2e}" % (\
+    a.l[0][1], log(a.l[0][1]/a.l[1][1])/log(2.), a.l[1][1], \
+    b.l[0][1], log(b.l[0][1]/b.l[1][1])/log(2.), b.l[1][1]),
+    print r"\\\"
+
+  print r"\hline"
+  print r"""\end{tabular}
+  \end{center}
+  \end{table}"""
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+
+for f in ['orderU','orderV','orderfU','orderfV']:
+   if (Curve(f,1,2) - Curve(f+'.ref',1,2)).max() > 1e-6 or\
+      (Curve(f,1,3) - Curve(f+'.ref',1,3)).max() > 1e-6 or\
+      (Curve(f,1,4) - Curve(f+'.ref',1,4)).max() > 1e-6:
+      exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/boundaries/orderU.ref b/test/boundaries/orderU.ref
new file mode 100644
index 0000000..d82e74d
--- /dev/null
+++ b/test/boundaries/orderU.ref
@@ -0,0 +1,2 @@
+7 3.722e-04 2.134e-03 6.678e-02
+8 1.016e-04 8.851e-04 4.408e-02
diff --git a/test/boundaries/orderV.ref b/test/boundaries/orderV.ref
new file mode 100644
index 0000000..ea22f34
--- /dev/null
+++ b/test/boundaries/orderV.ref
@@ -0,0 +1,2 @@
+7 3.999e-04 1.746e-03 5.347e-02
+8 1.067e-04 6.590e-04 3.287e-02
diff --git a/test/boundaries/orderfU.ref b/test/boundaries/orderfU.ref
new file mode 100644
index 0000000..7b7222c
--- /dev/null
+++ b/test/boundaries/orderfU.ref
@@ -0,0 +1,2 @@
+7 2.252e-04 4.771e-04 6.737e-03
+8 5.627e-05 1.230e-04 2.794e-03
diff --git a/test/boundaries/orderfV.ref b/test/boundaries/orderfV.ref
new file mode 100644
index 0000000..06d6d33
--- /dev/null
+++ b/test/boundaries/orderfV.ref
@@ -0,0 +1,2 @@
+7 2.818e-04 7.563e-04 9.280e-03
+8 7.034e-05 2.330e-04 3.691e-03
diff --git a/test/capwave/air-water/air-water.gfs b/test/capwave/air-water/air-water.gfs
new file mode 100644
index 0000000..863da20
--- /dev/null
+++ b/test/capwave/air-water/air-water.gfs
@@ -0,0 +1,65 @@
+# Title: Air-Water capillary wave
+#
+# Description:
+#
+# Same test as before but with density and viscosity ratio
+# corresponding to an air/water interface.
+#
+# \begin{table}[htbp]
+# \caption{\label{convergence}Convergence of the relative error between the analytical
+# solution and simulation results.}
+# \begin{center}
+# \begin{tabular}{|l|ccccc|} \hline
+# Method & $8^2$ & $16^2$ & $32^2$ & $64^2$ & $128^2$ \\ \hline
+# \input{convergence.tex} & 0.00313 \\
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# \begin{figure}[htbp]
+# \caption{\label{amplitude}Evolution of the amplitude of the capillary wave as a
+# function of non-dimensional time $\tau=\omega_0 t$.}
+# \begin{center}
+# \includegraphics[width=\hsize]{amplitude.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../capwave.sh air-water.gfs
+# Version: 1.2.0
+# Required files: convergence.ref prosperetti
+# Generated files: convergence.tex amplitude.eps
+#
+# Theoretical solution generated using:
+#  ~/local/src/laplace/oscillations planar 1 1 0.0182571749236 0.273038508 1 1 0.0012 0.01 0 0 | awk '{print $1*15.7402, ($2 > 0. ? $2 : -$2)}' > prosperetti
+#
+3 5 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 1.58928694288774963184 }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  Refine floor(LEVEL + 1 - (LEVEL - 2)*fabs(y)/1.5)
+  VariableTracerVOF T
+  VariableFiltered T1 T 1
+  VariableCurvature K T
+  SourceTension T 1 K
+  VariablePosition Y T y
+  Global {
+      #define VAR(T,min,max)   (min + CLAMP(T,0,1)*(max - min))
+      #define RHO(T)            VAR(T, 1.2/1000., 1.)
+      #define MU(T)             VAR(T, 1.8e-5/1.003e-3, 1.)
+  }
+  PhysicalParams { alpha = 1./RHO(T1) }
+  SourceViscosity 0.0182571749236*MU(T1)
+  InitFraction T (y - 0.01*cos (2.*M_PI*x))
+  OutputScalarNorm { step = 0.00198785108553814829 } {
+      awk '{printf ("%g %g\n", $3*15.7402, $9); fflush(stdout); }' > wave-LEVEL
+  } { v = (T > 0. && T < 1. ? Y : 0.) }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 1 right
+2 2 right
+3 3 right
+1 2 top
+1 3 bottom
diff --git a/test/capwave/air-water/convergence.ref b/test/capwave/air-water/convergence.ref
new file mode 100644
index 0000000..49c5880
--- /dev/null
+++ b/test/capwave/air-water/convergence.ref
@@ -0,0 +1,4 @@
+3 0.198686
+4 0.0750547
+5 0.0159213
+6 0.00576257
diff --git a/test/capwave/air-water/prosperetti b/test/capwave/air-water/prosperetti
new file mode 100644
index 0000000..e6a3434
--- /dev/null
+++ b/test/capwave/air-water/prosperetti
@@ -0,0 +1,800 @@
+0 0.01
+0.0312892 0.00999512
+0.0625783 0.00998051
+0.0938675 0.00995625
+0.125157 0.00992241
+0.156446 0.00987909
+0.187735 0.00982636
+0.219025 0.00976434
+0.250313 0.00969313
+0.281603 0.00961285
+0.312892 0.00952363
+0.344182 0.0094256
+0.37547 0.00931889
+0.40676 0.00920366
+0.438048 0.00908006
+0.469338 0.00894826
+0.500627 0.00880841
+0.531916 0.0086607
+0.563205 0.00850532
+0.594495 0.00834244
+0.625783 0.00817226
+0.657073 0.00799498
+0.688361 0.00781082
+0.719651 0.00761997
+0.75094 0.00742267
+0.78223 0.00721912
+0.813518 0.00700956
+0.844808 0.00679422
+0.876096 0.00657333
+0.907386 0.00634713
+0.938675 0.00611587
+0.969965 0.00587979
+1.00125 0.00563915
+1.03254 0.0053942
+1.06383 0.00514518
+1.09512 0.00489238
+1.12641 0.00463604
+1.1577 0.00437642
+1.18899 0.0041138
+1.22028 0.00384844
+1.25157 0.0035806
+1.28286 0.00331056
+1.31414 0.00303859
+1.34543 0.00276495
+1.37672 0.00248992
+1.40801 0.00221377
+1.4393 0.00193677
+1.47059 0.00165918
+1.50188 0.00138128
+1.53317 0.00110333
+1.56446 0.000825597
+1.59574 0.000548353
+1.62703 0.000271857
+1.65832 3.62942e-06
+1.68962 0.000277848
+1.72091 0.000550542
+1.7522 0.000821458
+1.78349 0.00109035
+1.81477 0.00135696
+1.84606 0.00162105
+1.87735 0.00188238
+1.90864 0.00214071
+1.93993 0.00239581
+1.97122 0.00264745
+2.0025 0.00289541
+2.03379 0.00313947
+2.06508 0.00337941
+2.09637 0.00361503
+2.12767 0.00384611
+2.15896 0.00407247
+2.19025 0.0042939
+2.22152 0.00451022
+2.25282 0.00472125
+2.28411 0.00492681
+2.3154 0.00512672
+2.34669 0.00532084
+2.37798 0.005509
+2.40927 0.00569104
+2.44055 0.00586683
+2.47184 0.00603622
+2.50313 0.00619909
+2.53442 0.00635532
+2.56572 0.00650477
+2.59701 0.00664735
+2.62828 0.00678295
+2.65957 0.00691148
+2.69087 0.00703284
+2.72216 0.00714696
+2.75345 0.00725376
+2.78474 0.00735317
+2.81603 0.00744514
+2.84731 0.00752962
+2.8786 0.00760655
+2.90989 0.0076759
+2.94118 0.00773765
+2.97247 0.00779177
+3.00377 0.00783825
+3.03506 0.00787707
+3.06633 0.00790824
+3.09762 0.00793177
+3.12892 0.00794766
+3.16021 0.00795595
+3.1915 0.00795666
+3.22279 0.00794983
+3.25408 0.00793549
+3.28536 0.00791371
+3.31665 0.00788453
+3.34794 0.00784802
+3.37923 0.00780425
+3.41052 0.0077533
+3.44182 0.00769524
+3.47309 0.00763018
+3.50438 0.00755821
+3.53567 0.00747942
+3.56697 0.00739393
+3.59826 0.00730185
+3.62955 0.0072033
+3.66084 0.00709841
+3.69212 0.0069873
+3.72341 0.00687011
+3.7547 0.00674699
+3.78599 0.00661808
+3.81728 0.00648352
+3.84857 0.00634349
+3.87986 0.00619813
+3.91114 0.00604761
+3.94243 0.0058921
+3.97372 0.00573177
+4.00502 0.0055668
+4.03631 0.00539737
+4.0676 0.00522366
+4.09887 0.00504585
+4.13017 0.00486414
+4.16146 0.00467873
+4.19275 0.00448979
+4.22404 0.00429754
+4.25533 0.00410216
+4.28662 0.00390387
+4.3179 0.00370286
+4.34919 0.00349934
+4.38048 0.00329352
+4.41177 0.0030856
+4.44306 0.0028758
+4.47436 0.00266431
+4.50565 0.00245135
+4.53692 0.00223714
+4.56822 0.00202187
+4.59951 0.00180577
+4.6308 0.00158903
+4.66209 0.00137188
+4.69338 0.00115452
+4.72467 0.000937154
+4.75595 0.000719994
+4.78724 0.000503245
+4.81853 0.000287112
+4.84982 7.17978e-05
+4.88111 0.000142497
+4.91241 0.000355573
+4.94368 0.000567232
+4.97497 0.000777281
+5.00627 0.000985526
+5.03756 0.00119178
+5.06885 0.00139585
+5.10014 0.00159756
+5.13143 0.00179673
+5.16271 0.00199317
+5.194 0.00218672
+5.22529 0.0023772
+5.25658 0.00256445
+5.28787 0.0027483
+5.31916 0.00292861
+5.35046 0.0031052
+5.38173 0.00327793
+5.41302 0.00344667
+5.44431 0.00361125
+5.47561 0.00377156
+5.5069 0.00392745
+5.53819 0.0040788
+5.56947 0.00422548
+5.60076 0.00436739
+5.63205 0.00450441
+5.66334 0.00463643
+5.69463 0.00476335
+5.72592 0.00488507
+5.75721 0.00500151
+5.78849 0.00511258
+5.81978 0.00521819
+5.85107 0.00531829
+5.88236 0.00541279
+5.91366 0.00550163
+5.94495 0.00558476
+5.97624 0.00566213
+6.00751 0.00573369
+6.03881 0.0057994
+6.0701 0.00585923
+6.10139 0.00591315
+6.13268 0.00596113
+6.16397 0.00600317
+6.19526 0.00603924
+6.22654 0.00606935
+6.25783 0.0060935
+6.28912 0.00611168
+6.32041 0.00612392
+6.35171 0.00613023
+6.383 0.00613063
+6.41427 0.00612516
+6.44556 0.00611384
+6.47686 0.00609672
+6.50815 0.00607384
+6.53944 0.00604525
+6.57073 0.006011
+6.60202 0.00597117
+6.6333 0.0059258
+6.66459 0.00587498
+6.69588 0.00581878
+6.72717 0.00575728
+6.75846 0.00569055
+6.78976 0.00561871
+6.82105 0.00554182
+6.85232 0.00546
+6.88361 0.00537335
+6.91491 0.00528197
+6.9462 0.00518598
+6.97749 0.00508548
+7.00878 0.0049806
+7.04006 0.00487145
+7.07135 0.00475817
+7.10264 0.00464088
+7.13393 0.00451971
+7.16522 0.0043948
+7.19651 0.00426629
+7.22781 0.00413431
+7.25908 0.003999
+7.29037 0.00386052
+7.32166 0.00371902
+7.35296 0.00357463
+7.38425 0.00342752
+7.41554 0.00327783
+7.44683 0.00312573
+7.47811 0.00297137
+7.5094 0.0028149
+7.54069 0.0026565
+7.57198 0.00249631
+7.60327 0.0023345
+7.63456 0.00217124
+7.66586 0.00200668
+7.69713 0.00184099
+7.72842 0.00167433
+7.75971 0.00150687
+7.79101 0.00133877
+7.8223 0.0011702
+7.85359 0.00100131
+7.88486 0.000832271
+7.91616 0.000663246
+7.94745 0.000494394
+7.97874 0.000325876
+8.01003 0.000157852
+8.04132 9.52121e-06
+8.07261 0.000176087
+8.10389 0.000341689
+8.13518 0.000506175
+8.16647 0.000669393
+8.19776 0.000831194
+8.22906 0.00099143
+8.26035 0.00114996
+8.29164 0.00130663
+8.32291 0.00146131
+8.35421 0.00161385
+8.3855 0.00176413
+8.41679 0.00191201
+8.44808 0.00205736
+8.47937 0.00220006
+8.51065 0.00233998
+8.54194 0.00247699
+8.57323 0.002611
+8.60452 0.00274187
+8.63581 0.00286951
+8.66711 0.0029938
+8.6984 0.00311465
+8.72967 0.00323195
+8.76096 0.00334562
+8.79226 0.00345555
+8.82355 0.00356167
+8.85484 0.00366388
+8.88613 0.00376212
+8.91742 0.0038563
+8.9487 0.00394637
+8.97999 0.00403224
+9.01128 0.00411387
+9.04257 0.00419118
+9.07386 0.00426414
+9.10515 0.00433269
+9.13645 0.00439679
+9.16772 0.00445639
+9.19901 0.00451147
+9.23031 0.00456199
+9.2616 0.00460793
+9.29289 0.00464926
+9.32418 0.00468597
+9.35546 0.00471805
+9.38675 0.00474549
+9.41804 0.00476828
+9.44933 0.00478642
+9.48062 0.00479993
+9.51191 0.0048088
+9.5432 0.00481306
+9.57448 0.00481272
+9.60577 0.00480781
+9.63706 0.00479835
+9.66835 0.00478438
+9.69965 0.00476592
+9.73094 0.00474303
+9.76223 0.00471573
+9.79351 0.00468409
+9.8248 0.00464814
+9.85609 0.00460795
+9.88738 0.00456358
+9.91867 0.00451508
+9.94996 0.00446253
+9.98124 0.004406
+10.0125 0.00434555
+10.0438 0.00428126
+10.0751 0.00421322
+10.1064 0.00414151
+10.1377 0.00406621
+10.169 0.00398742
+10.2003 0.00390522
+10.2316 0.00381971
+10.2628 0.00373099
+10.2941 0.00363915
+10.3254 0.00354431
+10.3567 0.00344657
+10.388 0.00334603
+10.4193 0.0032428
+10.4506 0.003137
+10.4819 0.00302873
+10.5132 0.00291812
+10.5445 0.00280528
+10.5757 0.00269033
+10.607 0.00257339
+10.6383 0.00245458
+10.6696 0.00233402
+10.7009 0.00221184
+10.7322 0.00208816
+10.7635 0.0019631
+10.7948 0.0018368
+10.826 0.00170938
+10.8573 0.00158096
+10.8886 0.00145167
+10.9199 0.00132165
+10.9512 0.00119101
+10.9825 0.00105989
+11.0138 0.000928413
+11.0451 0.000796705
+11.0764 0.000664895
+11.1077 0.000533107
+11.1389 0.000401468
+11.1702 0.000270103
+11.2015 0.000139135
+11.2328 8.68841e-06
+11.2641 0.000121116
+11.2954 0.000250158
+11.3267 0.000378317
+11.358 0.000505476
+11.3893 0.000631519
+11.4206 0.00075633
+11.4518 0.000879796
+11.4831 0.00100181
+11.5144 0.00112225
+11.5457 0.00124103
+11.577 0.00135802
+11.6083 0.00147314
+11.6396 0.00158628
+11.6709 0.00169733
+11.7021 0.00180622
+11.7334 0.00191283
+11.7647 0.00201709
+11.796 0.0021189
+11.8273 0.00221818
+11.8586 0.00231484
+11.8899 0.00240882
+11.9212 0.00250002
+11.9525 0.00258838
+11.9838 0.00267382
+12.015 0.00275629
+12.0463 0.00283571
+12.0776 0.00291203
+12.1089 0.00298518
+12.1402 0.00305512
+12.1715 0.00312179
+12.2028 0.00318513
+12.2341 0.00324513
+12.2654 0.00330172
+12.2966 0.00335487
+12.3279 0.00340455
+12.3592 0.00345073
+12.3905 0.00349338
+12.4218 0.00353247
+12.4531 0.003568
+12.4844 0.00359993
+12.5157 0.00362827
+12.547 0.00365299
+12.5782 0.00367409
+12.6095 0.00369158
+12.6408 0.00370545
+12.6721 0.0037157
+12.7034 0.00372235
+12.7347 0.0037254
+12.766 0.00372488
+12.7973 0.00372079
+12.8286 0.00371316
+12.8599 0.00370201
+12.8911 0.00368738
+12.9224 0.00366929
+12.9537 0.00364778
+12.985 0.00362288
+13.0163 0.00359464
+13.0476 0.0035631
+13.0789 0.0035283
+13.1102 0.00349029
+13.1414 0.00344913
+13.1727 0.00340487
+13.204 0.00335757
+13.2353 0.00330729
+13.2666 0.00325409
+13.2979 0.00319803
+13.3292 0.00313919
+13.3605 0.00307762
+13.3918 0.00301342
+13.4231 0.00294664
+13.4543 0.00287737
+13.4856 0.00280568
+13.5169 0.00273166
+13.5482 0.00265538
+13.5795 0.00257694
+13.6108 0.00249641
+13.6421 0.00241388
+13.6734 0.00232944
+13.7047 0.00224318
+13.736 0.0021552
+13.7672 0.00206558
+13.7985 0.00197442
+13.8298 0.00188181
+13.8611 0.00178785
+13.8924 0.00169264
+13.9237 0.00159626
+13.955 0.00149883
+13.9863 0.00140043
+14.0175 0.00130117
+14.0488 0.00120115
+14.0801 0.00110045
+14.1114 0.000999197
+14.1427 0.000897472
+14.174 0.00079538
+14.2053 0.00069302
+14.2366 0.00059049
+14.2679 0.00048789
+14.2992 0.000385317
+14.3304 0.00028287
+14.3617 0.000180645
+14.393 7.87392e-05
+14.4243 2.27518e-05
+14.4556 0.000123733
+14.4869 0.000224111
+14.5182 0.000323793
+14.5495 0.000422687
+14.5808 0.000520702
+14.612 0.000617749
+14.6433 0.00071374
+14.6746 0.00080859
+14.7059 0.000902212
+14.7372 0.000994524
+14.7685 0.00108544
+14.7998 0.00117489
+14.8311 0.00126279
+14.8624 0.00134906
+14.8936 0.00143363
+14.9249 0.00151642
+14.9562 0.00159738
+14.9875 0.00167642
+15.0188 0.00175348
+15.0501 0.0018285
+15.0814 0.00190142
+15.1127 0.00197217
+15.144 0.00204071
+15.1753 0.00210697
+15.2065 0.0021709
+15.2378 0.00223246
+15.2691 0.00229159
+15.3004 0.00234826
+15.3317 0.00240241
+15.363 0.00245402
+15.3943 0.00250304
+15.4256 0.00254944
+15.4568 0.00259319
+15.4881 0.00263425
+15.5194 0.00267262
+15.5507 0.00270825
+15.582 0.00274113
+15.6133 0.00277124
+15.6446 0.00279857
+15.6759 0.0028231
+15.7072 0.00284482
+15.7385 0.00286374
+15.7698 0.00287983
+15.801 0.00289311
+15.8323 0.00290356
+15.8636 0.00291121
+15.8949 0.00291604
+15.9262 0.00291808
+15.9574 0.00291733
+15.9887 0.00291381
+16.0201 0.00290753
+16.0514 0.00289851
+16.0827 0.00288679
+16.1139 0.00287237
+16.1452 0.00285529
+16.1765 0.00283557
+16.2078 0.00281325
+16.239 0.00278837
+16.2703 0.00276095
+16.3017 0.00273104
+16.333 0.00269868
+16.3643 0.0026639
+16.3955 0.00262677
+16.4268 0.00258731
+16.4581 0.00254559
+16.4894 0.00250165
+16.5208 0.00245554
+16.5519 0.00240732
+16.5832 0.00235705
+16.6146 0.00230478
+16.6459 0.00225058
+16.6771 0.0021945
+16.7084 0.00213661
+16.7397 0.00207697
+16.771 0.00201564
+16.8023 0.0019527
+16.8335 0.00188821
+16.8648 0.00182224
+16.8962 0.00175486
+16.9275 0.00168614
+16.9588 0.00161616
+16.99 0.00154498
+17.0213 0.00147269
+17.0526 0.00139934
+17.0839 0.00132503
+17.1151 0.00124983
+17.1464 0.0011738
+17.1778 0.00109704
+17.2091 0.00101961
+17.2404 0.000941588
+17.2716 0.000863058
+17.3029 0.000784096
+17.3342 0.000704778
+17.3655 0.000625182
+17.3969 0.000545385
+17.428 0.000465464
+17.4593 0.000385496
+17.4907 0.000305557
+17.522 0.000225724
+17.5532 0.000146072
+17.5845 6.66762e-05
+17.6158 1.23887e-05
+17.6471 9.1049e-05
+17.6784 0.000169232
+17.7096 0.000246864
+17.7409 0.000323876
+17.7723 0.000400196
+17.8036 0.000475755
+17.8349 0.000550484
+17.8661 0.000624317
+17.8974 0.000697188
+17.9287 0.00076903
+17.96 0.000839782
+17.9912 0.000909381
+18.0225 0.000977765
+18.0539 0.00104488
+18.0852 0.00111066
+18.1165 0.00117505
+18.1477 0.001238
+18.179 0.00129946
+18.2103 0.00135937
+18.2416 0.00141768
+18.273 0.00147436
+18.3041 0.00152934
+18.3354 0.00158259
+18.3668 0.00163406
+18.3981 0.00168371
+18.4293 0.00173152
+18.4606 0.00177743
+18.4919 0.00182141
+18.5232 0.00186343
+18.5545 0.00190347
+18.5857 0.00194149
+18.617 0.00197746
+18.6484 0.00201137
+18.6797 0.00204319
+18.7108 0.00207289
+18.7422 0.00210047
+18.7735 0.0021259
+18.8048 0.00214918
+18.8361 0.00217028
+18.8673 0.00218921
+18.8986 0.00220595
+18.93 0.0022205
+18.9613 0.00223285
+18.9926 0.00224301
+19.0238 0.00225097
+19.0551 0.00225674
+19.0864 0.00226032
+19.1177 0.00226172
+19.1489 0.00226096
+19.1802 0.00225803
+19.2115 0.00225296
+19.2429 0.00224576
+19.2742 0.00223645
+19.3054 0.00222504
+19.3367 0.00221157
+19.368 0.00219604
+19.3993 0.00217849
+19.4306 0.00215894
+19.4618 0.00213742
+19.4931 0.00211396
+19.5245 0.00208859
+19.5558 0.00206136
+19.5869 0.00203228
+19.6183 0.0020014
+19.6496 0.00196876
+19.6809 0.00193439
+19.7122 0.00189834
+19.7434 0.00186065
+19.7747 0.00182137
+19.8061 0.00178054
+19.8374 0.0017382
+19.8687 0.0016944
+19.8999 0.0016492
+19.9312 0.00160264
+19.9625 0.00155478
+19.9938 0.00150566
+20.025 0.00145534
+20.0563 0.00140387
+20.0876 0.00135131
+20.119 0.00129771
+20.1503 0.00124313
+20.1815 0.00118763
+20.2128 0.00113126
+20.2441 0.00107409
+20.2754 0.00101616
+20.3067 0.000957546
+20.3379 0.000898298
+20.3692 0.000838478
+20.4006 0.000778147
+20.4319 0.000717363
+20.463 0.000656187
+20.4944 0.00059468
+20.5257 0.000532902
+20.557 0.000470914
+20.5883 0.000408774
+20.6195 0.000346544
+20.6508 0.000284284
+20.6822 0.000222052
+20.7135 0.000159908
+20.7448 9.79118e-05
+20.776 3.61205e-05
+20.8073 2.54074e-05
+20.8386 8.66144e-05
+20.8699 0.000147444
+20.9011 0.000207839
+20.9324 0.000267746
+20.9637 0.000327108
+20.9951 0.000385871
+21.0264 0.000443984
+21.0576 0.000501393
+21.0889 0.000558047
+21.1202 0.000613896
+21.1515 0.00066889
+21.1828 0.000722981
+21.214 0.000776122
+21.2453 0.000828267
+21.2767 0.000879371
+21.308 0.00092939
+21.3391 0.000978281
+21.3705 0.001026
+21.4018 0.00107252
+21.4331 0.00111779
+21.4644 0.00116177
+21.4956 0.00120444
+21.5269 0.00124575
+21.5583 0.00128567
+21.5896 0.00132418
+21.6209 0.00136124
+21.6521 0.00139682
+21.6834 0.0014309
+21.7147 0.00146346
+21.746 0.00149446
+21.7772 0.00152388
+21.8085 0.00155172
+21.8398 0.00157794
+21.8712 0.00160253
+21.9025 0.00162548
+21.9337 0.00164676
+21.965 0.00166638
+21.9963 0.00168431
+22.0276 0.00170055
+22.0589 0.0017151
+22.0901 0.00172794
+22.1214 0.00173907
+22.1528 0.00174849
+22.1841 0.00175621
+22.2152 0.00176221
+22.2466 0.00176651
+22.2779 0.0017691
+22.3092 0.00177
+22.3405 0.0017692
+22.3717 0.00176673
+22.403 0.00176259
+22.4343 0.00175679
+22.4657 0.00174934
+22.4968 0.00174027
+22.5282 0.00172958
+22.5595 0.0017173
+22.5908 0.00170345
+22.6221 0.00168804
+22.6533 0.0016711
+22.6846 0.00165265
+22.7159 0.00163272
+22.7473 0.00161133
+22.7786 0.00158852
+22.8098 0.0015643
+22.8411 0.00153871
+22.8724 0.00151178
+22.9037 0.00148355
+22.9349 0.00145404
+22.9662 0.0014233
+22.9975 0.00139134
+23.0289 0.00135822
+23.0602 0.00132398
+23.0913 0.00128863
+23.1227 0.00125224
+23.154 0.00121483
+23.1853 0.00117645
+23.2166 0.00113714
+23.2478 0.00109694
+23.2791 0.00105589
+23.3104 0.00101404
+23.3418 0.000971429
+23.3729 0.000928104
+23.4043 0.000884109
+23.4356 0.000839489
+23.4669 0.000794289
+23.4982 0.000748556
+23.5294 0.000702336
+23.5607 0.000655676
+23.592 0.000608621
+23.6234 0.000561219
+23.6547 0.000513517
+23.6859 0.000465562
+23.7172 0.0004174
+23.7485 0.000369079
+23.7798 0.000320645
+23.811 0.000272146
+23.8423 0.000223628
+23.8736 0.000175137
+23.905 0.000126719
+23.9363 7.84201e-05
+23.9674 3.02862e-05
+23.9988 1.7638e-05
+24.0301 6.53077e-05
+24.0614 0.000112679
+24.0927 0.000159707
+24.1239 0.00020635
+24.1552 0.000252565
+24.1865 0.00029831
+24.2179 0.000343542
+24.249 0.000388223
+24.2804 0.000432312
+24.3117 0.000475769
+24.343 0.000518557
+24.3743 0.000560638
+24.4055 0.000601974
+24.4368 0.000642531
+24.4681 0.000682274
+24.4995 0.000721168
+24.5308 0.00075918
+24.562 0.00079628
+24.5933 0.000832435
+24.6246 0.000867615
+24.6559 0.000901793
+24.6871 0.00093494
+24.7184 0.000967031
+24.7497 0.000998038
+24.7811 0.00102794
+24.8124 0.00105671
+24.8435 0.00108433
+24.8749 0.00111077
+24.9062 0.00113603
+24.9375 0.00116007
+24.9688 0.00118289
+25 0.00120446
diff --git a/test/capwave/capwave.gfs b/test/capwave/capwave.gfs
new file mode 100644
index 0000000..20e7f9d
--- /dev/null
+++ b/test/capwave/capwave.gfs
@@ -0,0 +1,84 @@
+# Title: Planar capillary waves
+#
+# Description:
+#
+# A small amplitude sinusoidal wave oscillates under surface
+# tension. Prosperetti \cite{prosperetti81} found a solution to this
+# initial value problem in the limit of a vanishingly small initial
+# amplitude.
+#
+# The domain size is 1x3 units, large enough to minimise the effect of
+# boundaries (Prosperetti's theory is valid for infinite domains).
+#
+# Table \ref{convergence} shows the convergence of various solvers as
+# a function of resolution: Gerris, the marker technique of
+# \cite{popinet99}, Surfer \cite{gueyffier98}, PROST and CLSVOF
+# \cite{gerlach2006}. The same data is represented on Figure \ref{fig-convergence}.
+#
+# The time-evolution of the amplitude given by Prosperetti's theory
+# and Gerris ($64^2$) is given on Figure \ref{amplitude}.
+#
+# \begin{table}[htbp]
+# \caption{\label{convergence}Convergence of the relative error between the analytical
+# solution and simulation results from various solvers.}
+# \begin{center}
+# \begin{tabular}{|l|ccccc|} \hline
+# Method & $8^2$ & $16^2$ & $32^2$ & $64^2$ & $128^2$ \\ \hline
+# \input{convergence.tex} & 0.000545 \\
+# \input{markers.tex} \\
+# \input{surfer.tex} \\
+# \input{prost.tex} \\
+# \input{clsvof.tex} \\ \hline
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# \begin{figure}[htbp]
+# \caption{\label{fig-convergence}Convergence of the RMS error as a
+# function of resolution (number of grid points per wavelength) for
+# the methods indicated in the legend.}
+# \begin{center}
+# \includegraphics[width=\hsize]{convergence.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{amplitude}Evolution of the amplitude of the capillary wave as a
+# function of non-dimensional time $\tau=\omega_0 t$.}
+# \begin{center}
+# \includegraphics[width=\hsize]{amplitude.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh capwave.sh capwave.gfs
+# Version: 1.1.0
+# Required files: capwave.sh convergence.ref prosperetti markers.tex surfer.tex prost.tex clsvof.tex
+# Generated files: convergence.tex amplitude.eps convergence.eps markers.tex surfer.tex prost.tex clsvof.tex
+#
+3 5 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 2.2426211256 }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  # Decrease the resolution linearly down to 3 levels close to the
+  # bottom and top boundaries
+  Refine floor(LEVEL + 1 - (LEVEL - 2)*fabs(y)/1.5)
+  VariableTracerVOF T
+  VariableCurvature K T
+  SourceTension T 1 K
+  VariablePosition Y T y
+  SourceDiffusion U 0.0182571749236
+  SourceDiffusion V 0.0182571749236
+  InitFraction T (y - 0.01*cos (2.*M_PI*x))
+  OutputScalarNorm { step = 3.04290519077e-3 } {
+      awk '{printf ("%g %g\n", $3*11.1366559937, $9); fflush(stdout); }' > wave-LEVEL
+  } { v = (T > 0. && T < 1. ? Y : 0.) }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 1 right
+2 2 right
+3 3 right
+1 2 top
+1 3 bottom
diff --git a/test/capwave/capwave.sh b/test/capwave/capwave.sh
new file mode 100644
index 0000000..d2dc43f
--- /dev/null
+++ b/test/capwave/capwave.sh
@@ -0,0 +1,74 @@
+levels="3 4 5 6"
+
+if ! $donotrun; then
+    for level in $levels; do
+	if sed "s/LEVEL/$level/g" < $1 | gerris2D -; then
+	    :
+	else
+	    exit 1;
+	fi
+    done
+fi
+
+rm -f convergence
+for level in $levels; do
+    if awk -v level=$level 'BEGIN {s = 0.; n = 0; } {
+          t = $1; y = $2;
+          getline < "prosperetti"
+          s += (y - $2)*(y - $2);
+          n += 1;
+        }
+        END {
+          s = sqrt (s/n)/0.01;
+          printf ("%d %g\n", level, s);
+        }' < wave-$level >> convergence; then
+	:
+    else
+	exit 1;
+    fi
+done
+
+awk 'BEGIN{first=1}{ 
+  if (first) printf("Gerris &\n%.5f",$2);
+  else printf(" &\n%.5f",$2);
+  first=0;
+}' < convergence > convergence.tex
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'amplitude.eps'
+    set xlabel 'tau'
+    set ylabel 'Relative amplitude'
+    plot 'prosperetti' w l t "Prosperetti", 'wave-6' every 10 w p t "Gerris"
+EOF
+else
+    exit 1
+fi
+
+if test -f clsvof.tex ; then
+    cp convergence.tex gerris.tex
+    echo " &\n0.00060" >> gerris.tex
+    if cat <<EOF | gnuplot ; then :
+      set term postscript eps color lw 3 solid 20
+      set output 'convergence.eps'
+      set xlabel 'Number of grid points'
+      set ylabel 'Relative RMS error'
+      set logscale y
+      set logscale x 2
+      set grid
+      plot [5:200][1e-4:1]'gerris.tex' u (2**(\$0 + 2)):1 t "Gerris" w lp, 'prost.tex' u (2**(\$0 + 2)):1 t "PROST" w lp, 'markers.tex' u (2**(\$0 + 2)):1 t "Markers" w lp, 'clsvof.tex' u (2**(\$0 + 2)):1 t "CLSVOF" w lp, 'surfer.tex' u (2**(\$0 + 2)):1 t "Surfer" w lp, 2./x**2 t "Second order"
+EOF
+    else
+	exit 1
+    fi
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('convergence',1,2) - Curve('convergence.ref',1,2)).max() > 1e-5:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/capwave/clsvof.tex b/test/capwave/clsvof.tex
new file mode 100644
index 0000000..58f5db5
--- /dev/null
+++ b/test/capwave/clsvof.tex
@@ -0,0 +1,5 @@
+CLSVOF &
+0.3169 &
+0.0991 &
+0.0131 &
+0.0033
diff --git a/test/capwave/convergence.ref b/test/capwave/convergence.ref
new file mode 100644
index 0000000..51dab6a
--- /dev/null
+++ b/test/capwave/convergence.ref
@@ -0,0 +1,4 @@
+3 0.156991
+4 0.0282426
+5 0.00862894
+6 0.00183428
diff --git a/test/capwave/density/convergence.ref b/test/capwave/density/convergence.ref
new file mode 100644
index 0000000..6ea8a0f
--- /dev/null
+++ b/test/capwave/density/convergence.ref
@@ -0,0 +1,4 @@
+3 0.145919
+4 0.0423646
+5 0.00485021
+6 0.00141383
diff --git a/test/capwave/density/density.gfs b/test/capwave/density/density.gfs
new file mode 100644
index 0000000..342a631
--- /dev/null
+++ b/test/capwave/density/density.gfs
@@ -0,0 +1,66 @@
+# Title: Fluids of different densities
+#
+# Description:
+#
+# Same test as before but with a density ratio of 10. The dynamic
+# viscosities are identical.
+#
+# Table \ref{convergence} shows the convergence of various
+# solvers as a function of resolution: Gerris, the marker technique of
+# \cite{popinet99} and Surfer \cite{gueyffier98}.
+#
+# The time-evolution of the amplitude given by Prosperetti's theory
+# and Gerris ($64^2$) is given on Figure \ref{amplitude}.
+#
+# \begin{table}[htbp]
+# \caption{\label{convergence}Convergence of the relative error between the analytical
+# solution and simulation results from various solvers.}
+# \begin{center}
+# \begin{tabular}{|l|ccccc|} \hline
+# Method & $8^2$ & $16^2$ & $32^2$ & $64^2$ & $128^2$ \\ \hline
+# \input{convergence.tex} & 0.001155 \\
+# Markers & 0.3593 & 0.1397 & 0.0566 & 0.0264 & 0.0148 \\
+# Surfer & - & - & 0.1233 & 0.0300 & 0.0254 \\ \hline
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# \begin{figure}[htbp]
+# \caption{\label{amplitude}Evolution of the amplitude of the capillary wave as a
+# function of non-dimensional time $\tau=\omega_0 t$.}
+# \begin{center}
+# \includegraphics[width=\hsize]{amplitude.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../capwave.sh density.gfs
+# Version: 1.1.0
+# Required files: convergence.ref prosperetti
+# Generated files: convergence.tex amplitude.eps
+#
+3 5 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 1.66481717925811447992 }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  Refine floor(LEVEL + 1 - (LEVEL - 2)*fabs(y)/1.5)
+  VariableTracerVOF T
+  VariableCurvature K T
+  SourceTension T 1 K
+  VariablePosition Y T y
+  SourceDiffusion U 0.0182571749236
+  SourceDiffusion V 0.0182571749236
+  PhysicalParams { alpha = 1./(T + 0.1*(1. - T)) }
+  InitFraction T (y - 0.01*cos (2.*M_PI*x))
+  OutputScalarNorm { step = .00225584983639310905 } {
+      awk '{printf ("%g %g\n", $3*15.016663878457, $9); fflush(stdout); }' > wave-LEVEL
+  } { v = (T > 0. && T < 1. ? Y : 0.) }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 1 right
+2 2 right
+3 3 right
+1 2 top
+1 3 bottom
diff --git a/test/capwave/density/prosperetti b/test/capwave/density/prosperetti
new file mode 100644
index 0000000..91d37ac
--- /dev/null
+++ b/test/capwave/density/prosperetti
@@ -0,0 +1,739 @@
+0 0.01
+0.033875 0.00999439
+0.067751 0.00997778
+0.10163 0.00995043
+0.1355 0.00991252
+0.16938 0.00986426
+0.20325 0.00980582
+0.23713 0.00973741
+0.271 0.00965919
+0.30488 0.00957137
+0.33875 0.00947414
+0.37263 0.0093677
+0.4065 0.00925226
+0.44038 0.00912802
+0.47425 0.0089952
+0.50813 0.00885403
+0.54201 0.00870472
+0.57588 0.00854751
+0.60976 0.00838263
+0.64363 0.00821033
+0.67751 0.00803084
+0.71138 0.00784443
+0.74526 0.00765134
+0.77913 0.00745183
+0.81301 0.00724616
+0.84688 0.00703461
+0.88076 0.00681743
+0.91463 0.00659489
+0.94851 0.00636728
+0.98238 0.00613487
+1.0163 0.00589795
+1.0501 0.00565678
+1.084 0.00541165
+1.1179 0.00516286
+1.1518 0.00491067
+1.1856 0.00465539
+1.2195 0.00439729
+1.2534 0.00413667
+1.2873 0.00387381
+1.3211 0.00360899
+1.355 0.00334252
+1.3889 0.00307466
+1.4228 0.00280571
+1.4566 0.00253594
+1.4905 0.00226565
+1.5244 0.0019951
+1.5583 0.00172459
+1.5921 0.00145438
+1.626 0.00118474
+1.6599 0.000915948
+1.6938 0.000648269
+1.7276 0.000381966
+1.7615 0.000117299
+1.7954 0.000145477
+1.8293 0.00040611
+1.8631 0.000664353
+1.897 0.000919961
+1.9309 0.0011727
+1.9648 0.00142233
+1.9986 0.00166862
+2.0325 0.00191136
+2.0664 0.00215032
+2.1003 0.0023853
+2.1341 0.00261608
+2.168 0.00284246
+2.2019 0.00306426
+2.2358 0.00328128
+2.2696 0.00349334
+2.3035 0.00370027
+2.3374 0.00390189
+2.3713 0.00409805
+2.4051 0.00428859
+2.439 0.00447337
+2.4729 0.00465223
+2.5068 0.00482505
+2.5407 0.0049917
+2.5745 0.00515207
+2.6084 0.00530603
+2.6423 0.00545348
+2.6762 0.00559434
+2.71 0.0057285
+2.7439 0.00585588
+2.7778 0.00597641
+2.8117 0.00609003
+2.8455 0.00619667
+2.8794 0.00629628
+2.9133 0.00638881
+2.9472 0.00647424
+2.981 0.00655252
+3.0149 0.00662364
+3.0488 0.00668758
+3.0827 0.00674433
+3.1165 0.0067939
+3.1504 0.00683628
+3.1843 0.00687151
+3.2182 0.00689958
+3.252 0.00692055
+3.2859 0.00693443
+3.3198 0.00694128
+3.3537 0.00694114
+3.3875 0.00693406
+3.4214 0.00692012
+3.4553 0.00689937
+3.4892 0.00687189
+3.523 0.00683777
+3.5569 0.00679709
+3.5908 0.00674995
+3.6247 0.00669644
+3.6585 0.00663666
+3.6924 0.00657074
+3.7263 0.00649877
+3.7602 0.00642089
+3.794 0.00633722
+3.8279 0.00624789
+3.8618 0.00615304
+3.8957 0.00605279
+3.9295 0.00594731
+3.9634 0.00583673
+3.9973 0.00572121
+4.0312 0.0056009
+4.065 0.00547597
+4.0989 0.00534657
+4.1328 0.00521287
+4.1667 0.00507504
+4.2005 0.00493325
+4.2344 0.00478768
+4.2683 0.00463849
+4.3022 0.00448588
+4.336 0.00433003
+4.3699 0.0041711
+4.4038 0.0040093
+4.4377 0.0038448
+4.4715 0.00367779
+4.5054 0.00350847
+4.5393 0.00333701
+4.5732 0.00316361
+4.607 0.00298846
+4.6409 0.00281174
+4.6748 0.00263366
+4.7087 0.00245439
+4.7425 0.00227413
+4.7764 0.00209307
+4.8103 0.0019114
+4.8442 0.0017293
+4.878 0.00154695
+4.9119 0.00136456
+4.9458 0.00118229
+4.9797 0.00100034
+5.0136 0.000818878
+5.0474 0.000638086
+5.0813 0.000458142
+5.1152 0.000279219
+5.1491 0.000101489
+5.1829 7.48791e-05
+5.2168 0.000249719
+5.2507 0.000422866
+5.2846 0.000594161
+5.3184 0.000763445
+5.3523 0.000930566
+5.3862 0.00109537
+5.4201 0.00125772
+5.4539 0.00141745
+5.4878 0.00157445
+5.5217 0.00172856
+5.5556 0.00187966
+5.5894 0.00202762
+5.6233 0.00217232
+5.6572 0.00231363
+5.6911 0.00245145
+5.7249 0.00258565
+5.7588 0.00271614
+5.7927 0.00284282
+5.8266 0.00296558
+5.8604 0.00308434
+5.8943 0.00319901
+5.9282 0.0033095
+5.9621 0.00341574
+5.9959 0.00351766
+6.0298 0.00361519
+6.0637 0.00370826
+6.0976 0.00379682
+6.1314 0.00388081
+6.1653 0.0039602
+6.1992 0.00403492
+6.2331 0.00410496
+6.2669 0.00417027
+6.3008 0.00423082
+6.3347 0.0042866
+6.3686 0.00433759
+6.4024 0.00438377
+6.4363 0.00442514
+6.4702 0.00446169
+6.5041 0.00449343
+6.5379 0.00452036
+6.5718 0.00454249
+6.6057 0.00455985
+6.6396 0.00457245
+6.6734 0.00458032
+6.7073 0.00458348
+6.7412 0.00458198
+6.7751 0.00457585
+6.8089 0.00456514
+6.8428 0.00454989
+6.8767 0.00453015
+6.9106 0.00450599
+6.9444 0.00447746
+6.9783 0.00444463
+7.0122 0.00440756
+7.0461 0.00436632
+7.0799 0.004321
+7.1138 0.00427167
+7.1477 0.00421841
+7.1816 0.0041613
+7.2154 0.00410044
+7.2493 0.00403592
+7.2832 0.00396783
+7.3171 0.00389627
+7.3509 0.00382134
+7.3848 0.00374314
+7.4187 0.00366177
+7.4526 0.00357736
+7.4864 0.00349
+7.5203 0.0033998
+7.5542 0.00330688
+7.5881 0.00321137
+7.622 0.00311336
+7.6558 0.00301299
+7.6897 0.00291037
+7.7236 0.00280562
+7.7575 0.00269887
+7.7913 0.00259024
+7.8252 0.00247985
+7.8591 0.00236784
+7.893 0.00225432
+7.9268 0.00213943
+7.9607 0.00202329
+7.9946 0.00190602
+8.0285 0.00178776
+8.0623 0.00166863
+8.0962 0.00154876
+8.1301 0.00142828
+8.164 0.00130731
+8.1978 0.00118598
+8.2317 0.00106441
+8.2656 0.000942728
+8.2995 0.000821059
+8.3333 0.000699524
+8.3672 0.000578244
+8.4011 0.000457341
+8.435 0.000336932
+8.4688 0.000217136
+8.5027 9.80675e-05
+8.5366 2.01585e-05
+8.5705 0.00013743
+8.6043 0.000253636
+8.6382 0.000368668
+8.6721 0.00048242
+8.706 0.000594787
+8.7398 0.000705667
+8.7737 0.00081496
+8.8076 0.00092257
+8.8415 0.0010284
+8.8753 0.00113236
+8.9092 0.00123435
+8.9431 0.0013343
+8.977 0.00143212
+9.0108 0.00152772
+9.0447 0.00162103
+9.0786 0.00171197
+9.1125 0.00180047
+9.1463 0.00188646
+9.1802 0.00196987
+9.2141 0.00205064
+9.248 0.00212871
+9.2818 0.00220403
+9.3157 0.00227653
+9.3496 0.00234617
+9.3835 0.0024129
+9.4173 0.00247668
+9.4512 0.00253746
+9.4851 0.00259521
+9.519 0.0026499
+9.5528 0.00270149
+9.5867 0.00274996
+9.6206 0.00279529
+9.6545 0.00283744
+9.6883 0.00287642
+9.7222 0.00291219
+9.7561 0.00294476
+9.79 0.00297411
+9.8238 0.00300025
+9.8577 0.00302316
+9.8916 0.00304286
+9.9255 0.00305935
+9.9593 0.00307264
+9.9932 0.00308274
+10.027 0.00308966
+10.061 0.00309343
+10.095 0.00309406
+10.129 0.00309159
+10.163 0.00308604
+10.196 0.00307743
+10.23 0.0030658
+10.264 0.0030512
+10.298 0.00303365
+10.332 0.00301319
+10.366 0.00298988
+10.4 0.00296376
+10.434 0.00293487
+10.467 0.00290327
+10.501 0.00286901
+10.535 0.00283216
+10.569 0.00279275
+10.603 0.00275086
+10.637 0.00270655
+10.671 0.00265988
+10.705 0.00261092
+10.738 0.00255974
+10.772 0.0025064
+10.806 0.00245097
+10.84 0.00239353
+10.874 0.00233416
+10.908 0.00227292
+10.942 0.0022099
+10.976 0.00214517
+11.009 0.00207881
+11.043 0.0020109
+11.077 0.00194153
+11.111 0.00187077
+11.145 0.0017987
+11.179 0.00172541
+11.213 0.00165098
+11.247 0.0015755
+11.28 0.00149906
+11.314 0.00142172
+11.348 0.00134359
+11.382 0.00126475
+11.416 0.00118527
+11.45 0.00110525
+11.484 0.00102477
+11.518 0.000943919
+11.551 0.000862776
+11.585 0.000781427
+11.619 0.000699955
+11.653 0.000618444
+11.687 0.000536976
+11.721 0.000455633
+11.755 0.000374495
+11.789 0.000293643
+11.822 0.000213156
+11.856 0.000133111
+11.89 5.35859e-05
+11.924 2.53436e-05
+11.958 0.000103602
+11.992 0.000181118
+12.026 0.000257817
+12.06 0.00033363
+12.093 0.000408487
+12.127 0.000482321
+12.161 0.000555066
+12.195 0.000626657
+12.229 0.000697031
+12.263 0.000766127
+12.297 0.000833887
+12.331 0.000900252
+12.364 0.000965166
+12.398 0.00102858
+12.432 0.00109043
+12.466 0.00115068
+12.5 0.00120928
+12.534 0.00126618
+12.568 0.00132134
+12.602 0.00137471
+12.636 0.00142626
+12.669 0.00147595
+12.703 0.00152374
+12.737 0.00156961
+12.771 0.00161351
+12.805 0.00165543
+12.839 0.00169534
+12.873 0.00173321
+12.907 0.00176902
+12.94 0.00180275
+12.974 0.00183438
+13.008 0.00186391
+13.042 0.00189131
+13.076 0.00191657
+13.11 0.0019397
+13.144 0.00196067
+13.178 0.0019795
+13.211 0.00199617
+13.245 0.00201068
+13.279 0.00202305
+13.313 0.00203327
+13.347 0.00204135
+13.381 0.00204731
+13.415 0.00205114
+13.449 0.00205287
+13.482 0.00205251
+13.516 0.00205008
+13.55 0.00204559
+13.584 0.00203907
+13.618 0.00203054
+13.652 0.00202003
+13.686 0.00200756
+13.72 0.00199316
+13.753 0.00197686
+13.787 0.0019587
+13.821 0.00193869
+13.855 0.00191689
+13.889 0.00189333
+13.923 0.00186804
+13.957 0.00184106
+13.991 0.00181244
+14.024 0.00178222
+14.058 0.00175044
+14.092 0.00171714
+14.126 0.00168237
+14.16 0.00164619
+14.194 0.00160862
+14.228 0.00156973
+14.262 0.00152957
+14.295 0.00148818
+14.329 0.00144562
+14.363 0.00140194
+14.397 0.00135719
+14.431 0.00131143
+14.465 0.0012647
+14.499 0.00121707
+14.533 0.0011686
+14.566 0.00111932
+14.6 0.00106931
+14.634 0.00101862
+14.668 0.000967305
+14.702 0.000915421
+14.736 0.000863025
+14.77 0.000810174
+14.804 0.000756927
+14.837 0.000703338
+14.871 0.000649466
+14.905 0.000595367
+14.939 0.000541096
+14.973 0.000486711
+15.007 0.000432267
+15.041 0.000377819
+15.075 0.000323422
+15.108 0.000269131
+15.142 0.000214999
+15.176 0.00016108
+15.21 0.000107427
+15.244 5.40904e-05
+15.278 1.12259e-06
+15.312 5.14263e-05
+15.346 0.000103507
+15.379 0.00015507
+15.413 0.000206068
+15.447 0.000256454
+15.481 0.000306182
+15.515 0.000355208
+15.549 0.000403487
+15.583 0.000450977
+15.617 0.000497637
+15.65 0.000543426
+15.684 0.000588304
+15.718 0.000632235
+15.752 0.000675182
+15.786 0.000717108
+15.82 0.00075798
+15.854 0.000797765
+15.888 0.000836433
+15.921 0.000873952
+15.955 0.000910295
+15.989 0.000945433
+16.023 0.000979343
+16.057 0.001012
+16.091 0.00104338
+16.125 0.00107346
+16.159 0.00110222
+16.192 0.00112965
+16.226 0.00115572
+16.26 0.00118042
+16.294 0.00120375
+16.328 0.00122567
+16.362 0.00124619
+16.396 0.0012653
+16.43 0.00128298
+16.463 0.00129924
+16.497 0.00131405
+16.531 0.00132744
+16.565 0.00133938
+16.599 0.00134988
+16.633 0.00135894
+16.667 0.00136657
+16.701 0.00137276
+16.734 0.00137752
+16.768 0.00138087
+16.802 0.0013828
+16.836 0.00138333
+16.87 0.00138246
+16.904 0.00138021
+16.938 0.0013766
+16.972 0.00137164
+17.005 0.00136533
+17.039 0.00135771
+17.073 0.00134878
+17.107 0.00133858
+17.141 0.00132711
+17.175 0.0013144
+17.209 0.00130048
+17.243 0.00128536
+17.276 0.00126907
+17.31 0.00125164
+17.344 0.0012331
+17.378 0.00121347
+17.412 0.00119277
+17.446 0.00117105
+17.48 0.00114833
+17.514 0.00112463
+17.547 0.0011
+17.581 0.00107446
+17.615 0.00104806
+17.649 0.00102081
+17.683 0.000992757
+17.717 0.000963935
+17.751 0.000934379
+17.785 0.000904123
+17.818 0.000873205
+17.852 0.00084166
+17.886 0.000809526
+17.92 0.000776839
+17.954 0.000743637
+17.988 0.000709957
+18.022 0.000675838
+18.056 0.000641316
+18.089 0.000606431
+18.123 0.000571219
+18.157 0.00053572
+18.191 0.000499971
+18.225 0.00046401
+18.259 0.000427876
+18.293 0.000391605
+18.327 0.000355236
+18.36 0.000318806
+18.394 0.000282352
+18.428 0.00024591
+18.462 0.000209519
+18.496 0.000173214
+18.53 0.00013703
+18.564 0.000101003
+18.598 6.51686e-05
+18.631 2.95609e-05
+18.665 5.78599e-06
+18.699 4.08387e-05
+18.733 7.55641e-05
+18.767 0.00010993
+18.801 0.000143905
+18.835 0.000177457
+18.869 0.000210557
+18.902 0.000243174
+18.936 0.00027528
+18.97 0.000306847
+19.004 0.000337846
+19.038 0.000368252
+19.072 0.000398039
+19.106 0.000427181
+19.14 0.000455654
+19.173 0.000483435
+19.207 0.000510502
+19.241 0.000536833
+19.275 0.000562408
+19.309 0.000587207
+19.343 0.00061121
+19.377 0.000634402
+19.411 0.000656763
+19.444 0.00067828
+19.478 0.000698937
+19.512 0.000718719
+19.546 0.000737615
+19.58 0.000755612
+19.614 0.000772699
+19.648 0.000788867
+19.682 0.000804106
+19.715 0.000818409
+19.749 0.000831769
+19.783 0.00084418
+19.817 0.000855638
+19.851 0.000866137
+19.885 0.000875676
+19.919 0.000884253
+19.953 0.000891866
+19.986 0.000898517
+20.02 0.000904205
+20.054 0.000908933
+20.088 0.000912703
+20.122 0.000915521
+20.156 0.00091739
+20.19 0.000918317
+20.224 0.000918308
+20.257 0.00091737
+20.291 0.000915512
+20.325 0.000912744
+20.359 0.000909075
+20.393 0.000904517
+20.427 0.00089908
+20.461 0.000892779
+20.495 0.000885625
+20.528 0.000877634
+20.562 0.00086882
+20.596 0.000859198
+20.63 0.000848784
+20.664 0.000837596
+20.698 0.000825652
+20.732 0.000812968
+20.766 0.000799564
+20.799 0.00078546
+20.833 0.000770674
+20.867 0.000755228
+20.901 0.000739142
+20.935 0.000722438
+20.969 0.000705138
+21.003 0.000687263
+21.037 0.000668837
+21.07 0.000649882
+21.104 0.000630422
+21.138 0.00061048
+21.172 0.000590081
+21.206 0.000569248
+21.24 0.000548006
+21.274 0.000526381
+21.308 0.000504396
+21.341 0.000482077
+21.375 0.000459449
+21.409 0.000436537
+21.443 0.000413367
+21.477 0.000389963
+21.511 0.000366353
+21.545 0.00034256
+21.579 0.000318611
+21.612 0.00029453
+21.646 0.000270344
+21.68 0.000246077
+21.714 0.000221755
+21.748 0.000197402
+21.782 0.000173044
+21.816 0.000148704
+21.85 0.000124407
+21.883 0.000100178
+21.917 7.60401e-05
+21.951 5.2017e-05
+21.985 2.81319e-05
+22.019 4.40794e-06
+22.053 1.91323e-05
+22.087 4.24667e-05
+22.121 6.55733e-05
+22.154 8.84306e-05
+22.188 0.000111018
+22.222 0.000133314
+22.256 0.000155299
+22.29 0.000176953
+22.324 0.000198258
+22.358 0.000219194
+22.392 0.000239744
+22.425 0.000259889
+22.459 0.000279614
+22.493 0.0002989
+22.527 0.000317733
+22.561 0.000336096
+22.595 0.000353976
+22.629 0.000371359
+22.663 0.000388229
+22.696 0.000404576
+22.73 0.000420386
+22.764 0.000435647
+22.798 0.00045035
+22.832 0.000464483
+22.866 0.000478038
+22.9 0.000491004
+22.934 0.000503373
+22.967 0.000515139
+23.001 0.000526293
+23.035 0.00053683
+23.069 0.000546744
+23.103 0.000556029
+23.137 0.000564683
+23.171 0.0005727
+23.205 0.000580078
+23.238 0.000586815
+23.272 0.000592909
+23.306 0.000598359
+23.34 0.000603165
+23.374 0.000607327
+23.408 0.000610846
+23.442 0.000613724
+23.476 0.000615963
+23.509 0.000617565
+23.543 0.000618535
+23.577 0.000618876
+23.611 0.000618594
+23.645 0.000617693
+23.679 0.000616179
+23.713 0.000614059
+23.747 0.00061134
+23.78 0.000608029
+23.814 0.000604134
+23.848 0.000599665
+23.882 0.000594629
+23.916 0.000589038
+23.95 0.0005829
+23.984 0.000576227
+24.018 0.000569029
+24.051 0.000561318
+24.085 0.000553105
+24.119 0.000544404
+24.153 0.000535227
+24.187 0.000525587
+24.221 0.000515496
+24.255 0.00050497
+24.289 0.000494022
+24.322 0.000482667
+24.356 0.000470919
+24.39 0.000458793
+24.424 0.000446305
+24.458 0.00043347
+24.492 0.000420303
+24.526 0.000406822
+24.56 0.000393041
+24.593 0.000378977
+24.627 0.000364646
+24.661 0.000350066
+24.695 0.000335252
+24.729 0.000320222
+24.763 0.000304992
+24.797 0.00028958
+24.831 0.000274002
+24.864 0.000258275
+24.898 0.000242417
+24.932 0.000226444
+24.966 0.000210374
+25 0.000194223
diff --git a/test/capwave/gravity/convergence.ref b/test/capwave/gravity/convergence.ref
new file mode 100644
index 0000000..145ac1e
--- /dev/null
+++ b/test/capwave/gravity/convergence.ref
@@ -0,0 +1,4 @@
+3 0.151397
+4 0.0324848
+5 0.00593384
+6 0.00635294
diff --git a/test/capwave/gravity/gravity.gfs b/test/capwave/gravity/gravity.gfs
new file mode 100644
index 0000000..107db7e
--- /dev/null
+++ b/test/capwave/gravity/gravity.gfs
@@ -0,0 +1,65 @@
+# Title: Pure gravity wave
+#
+# Description:
+#
+# Similar to the capillary wave test case but for a pure gravity
+# wave. The density ratio is 10. The dynamic viscosities are
+# identical.
+#
+# The time-evolution of the amplitude given by Prosperetti's theory
+# and Gerris ($64^2$) is given on Figure \ref{amplitude}.
+#
+# \begin{table}[htbp]
+# \caption{\label{convergence}Convergence of the relative error between the analytical
+# solution and simulation results.}
+# \begin{center}
+# \begin{tabular}{|l|ccccc|} \hline
+# Method & $8^2$ & $16^2$ & $32^2$ & $64^2$ & $128^2$ \\ \hline
+# \input{convergence.tex} & 0.00417707 \\
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# \begin{figure}[htbp]
+# \caption{\label{amplitude}Evolution of the amplitude of the gravity wave as a
+# function of non-dimensional time $\tau=\omega_0 t$.}
+# \begin{center}
+# \includegraphics[width=\hsize]{amplitude.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../capwave.sh gravity.gfs
+# Version: 1.0.0
+# Required files: convergence.ref prosperetti
+# Generated files: convergence.tex amplitude.eps
+#
+1 1 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 1.66481717925811447992 }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  Refine LEVEL
+  VariableTracerVOF {} T
+
+  # Line below is for direct imposition of gravity acceleration
+  #  Source {} V 50
+
+  # It is better to use a formulation where the first-order
+  # hydrostatic pressure is substracted away (in particular it
+  # prevents the generation of "hydrostatic spurious currents")
+  VariablePosition {} Y T y
+
+  # acceleration of gravity is 50, the equivalent "reduced pressure"
+  # is 50*(1. - 0.1) = 45
+  SourceTension {} T 45 Y
+
+  SourceDiffusion {} U 0.0182571749236
+  SourceDiffusion {} V 0.0182571749236
+  PhysicalParams { alpha = 1./(T + 0.1*(1. - T)) }
+  InitFraction {} T (y - 0.01*cos (2.*M_PI*x))
+  OutputScalarNorm { step = .00225584983639310905 } {
+      awk '{printf ("%g %g\n", $3*16.032448313657, $9); fflush(stdout); }' > wave-LEVEL
+  } { v = (T > 1e-6 && T < 1. - 1e-6 ? Y : 0.) }
+}
+GfsBox {}
+1 1 right
diff --git a/test/capwave/gravity/prosperetti b/test/capwave/gravity/prosperetti
new file mode 100644
index 0000000..d1a1a57
--- /dev/null
+++ b/test/capwave/gravity/prosperetti
@@ -0,0 +1,739 @@
+0 0.01
+0.036167 0.0099936
+0.072334 0.00997468
+0.1085 0.0099435
+0.14467 0.00990031
+0.18083 0.00984532
+0.217 0.00977877
+0.25317 0.00970087
+0.28933 0.00961185
+0.3255 0.00951193
+0.36167 0.00940137
+0.39783 0.00928039
+0.434 0.00914926
+0.47017 0.00900822
+0.50634 0.00885755
+0.5425 0.00869751
+0.57867 0.00852839
+0.61484 0.00835047
+0.651 0.00816404
+0.68717 0.0079694
+0.72334 0.00776686
+0.7595 0.00755673
+0.79567 0.00733931
+0.83184 0.00711494
+0.868 0.00688394
+0.90417 0.00664663
+0.94034 0.00640336
+0.9765 0.00615445
+1.0127 0.00590026
+1.0488 0.00564112
+1.085 0.00537737
+1.1212 0.00510938
+1.1573 0.00483749
+1.1935 0.00456204
+1.2297 0.00428339
+1.2658 0.0040019
+1.302 0.00371792
+1.3382 0.0034318
+1.3743 0.00314389
+1.4105 0.00285454
+1.4467 0.0025641
+1.4828 0.00227293
+1.519 0.00198136
+1.5552 0.00168974
+1.5913 0.0013984
+1.6275 0.0011077
+1.6637 0.00081795
+1.6998 0.000529491
+1.736 0.000242646
+1.7722 4.22646e-05
+1.8083 0.000324926
+1.8445 0.000605028
+1.8807 0.000882266
+1.9168 0.00115634
+1.953 0.00142696
+1.9892 0.00169384
+2.0253 0.0019567
+2.0615 0.00221526
+2.0977 0.00246927
+2.1338 0.00271846
+2.17 0.00296259
+2.2062 0.00320141
+2.2423 0.00343469
+2.2785 0.0036622
+2.3147 0.00388373
+2.3508 0.00409907
+2.387 0.00430802
+2.4232 0.00451038
+2.4593 0.00470599
+2.4955 0.00489466
+2.5317 0.00507624
+2.5678 0.00525057
+2.604 0.00541751
+2.6402 0.00557692
+2.6763 0.00572869
+2.7125 0.00587269
+2.7487 0.00600883
+2.7848 0.00613702
+2.821 0.00625715
+2.8572 0.00636918
+2.8933 0.00647302
+2.9295 0.00656863
+2.9657 0.00665595
+3.0018 0.00673497
+3.038 0.00680565
+3.0742 0.00686798
+3.1103 0.00692196
+3.1465 0.00696759
+3.1827 0.00700488
+3.2188 0.00703386
+3.255 0.00705457
+3.2912 0.00706704
+3.3273 0.00707133
+3.3635 0.0070675
+3.3997 0.00705561
+3.4358 0.00703576
+3.472 0.00700803
+3.5082 0.0069725
+3.5443 0.00692929
+3.5805 0.00687851
+3.6167 0.00682027
+3.6528 0.00675471
+3.689 0.00668196
+3.7252 0.00660216
+3.7613 0.00651546
+3.7975 0.00642202
+3.8337 0.006322
+3.8698 0.00621556
+3.906 0.00610289
+3.9422 0.00598415
+3.9783 0.00585955
+4.0145 0.00572926
+4.0507 0.00559349
+4.0868 0.00545243
+4.123 0.0053063
+4.1592 0.0051553
+4.1953 0.00499963
+4.2315 0.00483954
+4.2677 0.00467522
+4.3038 0.0045069
+4.34 0.00433482
+4.3762 0.0041592
+4.4123 0.00398027
+4.4485 0.00379826
+4.4847 0.0036134
+4.5208 0.00342595
+4.557 0.00323612
+4.5932 0.00304416
+4.6293 0.00285031
+4.6655 0.0026548
+4.7017 0.00245788
+4.7379 0.00225977
+4.774 0.00206073
+4.8102 0.00186098
+4.8464 0.00166077
+4.8825 0.00146032
+4.9187 0.00125987
+4.9549 0.00105965
+4.991 0.000859881
+5.0272 0.0006608
+5.0634 0.000462626
+5.0995 0.000265579
+5.1357 6.98778e-05
+5.1719 0.000124264
+5.208 0.000316636
+5.2442 0.00050703
+5.2804 0.000695245
+5.3165 0.000881081
+5.3527 0.00106434
+5.3889 0.00124484
+5.425 0.0014224
+5.4612 0.00159682
+5.4974 0.00176794
+5.5335 0.00193559
+5.5697 0.0020996
+5.6059 0.00225981
+5.642 0.00241608
+5.6782 0.00256824
+5.7144 0.00271617
+5.7505 0.00285972
+5.7867 0.00299877
+5.8229 0.00313319
+5.859 0.00326287
+5.8952 0.00338769
+5.9314 0.00350756
+5.9675 0.00362237
+6.0037 0.00373204
+6.0399 0.00383647
+6.076 0.0039356
+6.1122 0.00402935
+6.1484 0.00411766
+6.1845 0.00420047
+6.2207 0.00427773
+6.2569 0.0043494
+6.293 0.00441543
+6.3292 0.00447582
+6.3654 0.00453052
+6.4015 0.00457952
+6.4377 0.00462281
+6.4739 0.0046604
+6.51 0.00469227
+6.5462 0.00471845
+6.5824 0.00473895
+6.6185 0.00475379
+6.6547 0.00476301
+6.6909 0.00476663
+6.727 0.00476471
+6.7632 0.00475728
+6.7994 0.0047444
+6.8355 0.00472614
+6.8717 0.00470255
+6.9079 0.00467371
+6.944 0.00463969
+6.9802 0.00460058
+7.0164 0.00455646
+7.0525 0.00450742
+7.0887 0.00445357
+7.1249 0.004395
+7.161 0.00433182
+7.1972 0.00426414
+7.2334 0.00419208
+7.2695 0.00411575
+7.3057 0.00403528
+7.3419 0.00395079
+7.378 0.00386242
+7.4142 0.0037703
+7.4504 0.00367456
+7.4865 0.00357534
+7.5227 0.0034728
+7.5589 0.00336707
+7.595 0.0032583
+7.6312 0.00314665
+7.6674 0.00303226
+7.7035 0.00291529
+7.7397 0.0027959
+7.7759 0.00267424
+7.812 0.00255047
+7.8482 0.00242476
+7.8844 0.00229725
+7.9205 0.00216813
+7.9567 0.00203754
+7.9929 0.00190565
+8.029 0.00177262
+8.0652 0.00163862
+8.1014 0.0015038
+8.1375 0.00136834
+8.1737 0.00123239
+8.2099 0.00109611
+8.246 0.000959663
+8.2822 0.000823208
+8.3184 0.000686901
+8.3545 0.000550899
+8.3907 0.000415356
+8.4269 0.000280425
+8.463 0.000146256
+8.4992 1.29976e-05
+8.5354 0.000119203
+8.5715 0.000250204
+8.6077 0.000379862
+8.6439 0.000508039
+8.68 0.0006346
+8.7162 0.000759411
+8.7524 0.000882344
+8.7885 0.00100327
+8.8247 0.00112207
+8.8609 0.00123862
+8.897 0.00135281
+8.9332 0.00146452
+8.9694 0.00157364
+9.0055 0.00168008
+9.0417 0.00178373
+9.0779 0.00188449
+9.114 0.00198226
+9.1502 0.00207697
+9.1864 0.00216853
+9.2225 0.00225686
+9.2587 0.00234188
+9.2949 0.00242352
+9.331 0.00250171
+9.3672 0.0025764
+9.4034 0.00264752
+9.4395 0.00271503
+9.4757 0.00277887
+9.5119 0.002839
+9.548 0.00289538
+9.5842 0.00294798
+9.6204 0.00299677
+9.6565 0.00304172
+9.6927 0.00308281
+9.7289 0.00312002
+9.765 0.00315335
+9.8012 0.00318279
+9.8374 0.00320834
+9.8735 0.00322999
+9.9097 0.00324776
+9.9459 0.00326165
+9.982 0.00327169
+10.018 0.00327789
+10.054 0.00328027
+10.091 0.00327887
+10.127 0.00327372
+10.163 0.00326485
+10.199 0.0032523
+10.235 0.00323612
+10.271 0.00321636
+10.308 0.00319306
+10.344 0.0031663
+10.38 0.00313611
+10.416 0.00310257
+10.452 0.00306575
+10.488 0.0030257
+10.525 0.00298251
+10.561 0.00293625
+10.597 0.002887
+10.633 0.00283484
+10.669 0.00277985
+10.705 0.00272211
+10.742 0.00266173
+10.778 0.00259879
+10.814 0.00253338
+10.85 0.0024656
+10.886 0.00239554
+10.922 0.00232331
+10.959 0.00224901
+10.995 0.00217273
+11.031 0.00209459
+11.067 0.00201469
+11.103 0.00193313
+11.139 0.00185002
+11.176 0.00176547
+11.212 0.0016796
+11.248 0.0015925
+11.284 0.00150429
+11.32 0.00141508
+11.356 0.00132499
+11.393 0.00123411
+11.429 0.00114257
+11.465 0.00105048
+11.501 0.000957935
+11.537 0.000865059
+11.573 0.000771958
+11.61 0.00067874
+11.646 0.000585515
+11.682 0.00049239
+11.718 0.000399471
+11.754 0.000306864
+11.79 0.000214672
+11.827 0.000122999
+11.863 3.19457e-05
+11.899 5.8388e-05
+11.935 0.000147904
+11.971 0.000236506
+12.007 0.000324098
+12.044 0.00041059
+12.08 0.000495889
+12.116 0.000579908
+12.152 0.00066256
+12.188 0.000743761
+12.224 0.000823429
+12.261 0.000901486
+12.297 0.000977854
+12.333 0.00105246
+12.369 0.00112523
+12.405 0.0011961
+12.441 0.001265
+12.478 0.00133187
+12.514 0.00139664
+12.55 0.00145927
+12.586 0.00151969
+12.622 0.00157785
+12.658 0.00163371
+12.695 0.00168722
+12.731 0.00173834
+12.767 0.00178702
+12.803 0.00183324
+12.839 0.00187695
+12.875 0.00191814
+12.912 0.00195677
+12.948 0.00199281
+12.984 0.00202626
+13.02 0.00205709
+13.056 0.00208528
+13.092 0.00211083
+13.129 0.00213373
+13.165 0.00215397
+13.201 0.00217156
+13.237 0.00218649
+13.273 0.00219877
+13.309 0.0022084
+13.346 0.0022154
+13.382 0.00221979
+13.418 0.00222156
+13.454 0.00222076
+13.49 0.00221739
+13.526 0.00221149
+13.563 0.00220307
+13.599 0.00219218
+13.635 0.00217884
+13.671 0.00216309
+13.707 0.00214497
+13.743 0.00212452
+13.78 0.00210177
+13.816 0.00207678
+13.852 0.0020496
+13.888 0.00202026
+13.924 0.00198883
+13.96 0.00195536
+13.997 0.0019199
+14.033 0.0018825
+14.069 0.00184324
+14.105 0.00180216
+14.141 0.00175934
+14.177 0.00171483
+14.214 0.0016687
+14.25 0.00162102
+14.286 0.00157185
+14.322 0.00152126
+14.358 0.00146933
+14.394 0.00141612
+14.431 0.0013617
+14.467 0.00130616
+14.503 0.00124955
+14.539 0.00119196
+14.575 0.00113347
+14.611 0.00107413
+14.648 0.00101404
+14.684 0.00095326
+14.72 0.000891873
+14.756 0.000829954
+14.792 0.000767577
+14.828 0.000704819
+14.865 0.000641755
+14.901 0.00057846
+14.937 0.000515009
+14.973 0.000451477
+15.009 0.000387937
+15.045 0.000324463
+15.082 0.000261128
+15.118 0.000198003
+15.154 0.00013516
+15.19 7.26676e-05
+15.226 1.05965e-05
+15.262 5.09858e-05
+15.299 0.000112012
+15.335 0.000172417
+15.371 0.000232135
+15.407 0.000291104
+15.443 0.000349261
+15.479 0.000406547
+15.516 0.000462902
+15.552 0.000518269
+15.588 0.000572591
+15.624 0.000625817
+15.66 0.000677891
+15.696 0.000728765
+15.733 0.000778389
+15.769 0.000826716
+15.805 0.000873701
+15.841 0.000919301
+15.877 0.000963475
+15.913 0.00100618
+15.95 0.00104739
+15.986 0.00108706
+16.022 0.00112515
+16.058 0.00116165
+16.094 0.00119651
+16.13 0.00122971
+16.167 0.00126123
+16.203 0.00129105
+16.239 0.00131914
+16.275 0.00134549
+16.311 0.00137007
+16.347 0.00139288
+16.384 0.00141391
+16.42 0.00143314
+16.456 0.00145057
+16.492 0.00146618
+16.528 0.00147999
+16.564 0.00149198
+16.601 0.00150217
+16.637 0.00151054
+16.673 0.00151711
+16.709 0.00152188
+16.745 0.00152487
+16.781 0.00152608
+16.818 0.00152553
+16.854 0.00152322
+16.89 0.00151919
+16.926 0.00151345
+16.962 0.00150601
+16.998 0.00149691
+17.035 0.00148616
+17.071 0.00147379
+17.107 0.00145983
+17.143 0.0014443
+17.179 0.00142725
+17.215 0.00140869
+17.252 0.00138867
+17.288 0.00136722
+17.324 0.00134437
+17.36 0.00132016
+17.396 0.00129464
+17.432 0.00126784
+17.469 0.00123981
+17.505 0.00121057
+17.541 0.00118019
+17.577 0.00114871
+17.613 0.00111616
+17.649 0.00108259
+17.686 0.00104806
+17.722 0.00101261
+17.758 0.000976289
+17.794 0.000939143
+17.83 0.000901225
+17.866 0.000862583
+17.903 0.000823268
+17.939 0.000783332
+17.975 0.000742825
+18.011 0.000701798
+18.047 0.000660303
+18.083 0.000618392
+18.12 0.000576117
+18.156 0.000533528
+18.192 0.000490678
+18.228 0.000447619
+18.264 0.0004044
+18.3 0.000361075
+18.337 0.000317692
+18.373 0.000274304
+18.409 0.000230959
+18.445 0.000187708
+18.481 0.0001446
+18.517 0.000101682
+18.554 5.90034e-05
+18.59 1.66107e-05
+18.626 2.54493e-05
+18.662 6.71309e-05
+18.698 0.000108389
+18.734 0.00014918
+18.771 0.000189461
+18.807 0.000229189
+18.843 0.000268323
+18.879 0.000306822
+18.915 0.000344649
+18.951 0.000381764
+18.988 0.00041813
+19.024 0.000453713
+19.06 0.000488477
+19.096 0.000522388
+19.132 0.000555416
+19.168 0.000587529
+19.205 0.000618697
+19.241 0.000648892
+19.277 0.000678088
+19.313 0.00070626
+19.349 0.000733382
+19.385 0.000759433
+19.422 0.00078439
+19.458 0.000808236
+19.494 0.00083095
+19.53 0.000852516
+19.566 0.000872919
+19.602 0.000892145
+19.639 0.00091018
+19.675 0.000927015
+19.711 0.00094264
+19.747 0.000957046
+19.783 0.000970227
+19.819 0.000982177
+19.856 0.000992894
+19.892 0.00100237
+19.928 0.00101062
+19.964 0.00101763
+20 0.0010234
+20.036 0.00102794
+20.073 0.00103126
+20.109 0.00103335
+20.145 0.00103424
+20.181 0.00103392
+20.217 0.00103241
+20.253 0.00102971
+20.29 0.00102585
+20.326 0.00102084
+20.362 0.00101468
+20.398 0.0010074
+20.434 0.000999018
+20.47 0.000989547
+20.507 0.00097901
+20.543 0.000967427
+20.579 0.000954819
+20.615 0.000941211
+20.651 0.000926626
+20.687 0.000911088
+20.724 0.000894624
+20.76 0.000877259
+20.796 0.000859022
+20.832 0.000839941
+20.868 0.000820044
+20.904 0.000799361
+20.941 0.000777922
+20.977 0.000755759
+21.013 0.000732903
+21.049 0.000709385
+21.085 0.000685239
+21.121 0.000660497
+21.158 0.000635193
+21.194 0.00060936
+21.23 0.000583033
+21.266 0.000556246
+21.302 0.000529034
+21.338 0.000501431
+21.375 0.000473473
+21.411 0.000445194
+21.447 0.000416631
+21.483 0.000387817
+21.519 0.00035879
+21.555 0.000329582
+21.592 0.000300231
+21.628 0.000270771
+21.664 0.000241236
+21.7 0.000211662
+21.736 0.000182083
+21.772 0.000152532
+21.809 0.000123044
+21.845 9.3653e-05
+21.881 6.4391e-05
+21.917 3.52911e-05
+21.953 6.38543e-06
+21.989 2.22942e-05
+22.026 5.07166e-05
+22.062 7.88511e-05
+22.098 0.000106668
+22.134 0.000134137
+22.17 0.000161229
+22.206 0.000187918
+22.243 0.000214174
+22.279 0.000239972
+22.315 0.000265285
+22.351 0.000290088
+22.387 0.000314357
+22.423 0.000338069
+22.46 0.000361199
+22.496 0.000383727
+22.532 0.000405631
+22.568 0.000426892
+22.604 0.000447489
+22.64 0.000467405
+22.677 0.000486623
+22.713 0.000505125
+22.749 0.000522897
+22.785 0.000539923
+22.821 0.000556191
+22.857 0.000571688
+22.894 0.000586402
+22.93 0.000600322
+22.966 0.00061344
+23.002 0.000625746
+23.038 0.000637233
+23.074 0.000647894
+23.111 0.000657724
+23.147 0.000666719
+23.183 0.000674874
+23.219 0.000682188
+23.255 0.000688659
+23.291 0.000694285
+23.328 0.000699068
+23.364 0.00070301
+23.4 0.000706111
+23.436 0.000708376
+23.472 0.000709809
+23.508 0.000710415
+23.545 0.0007102
+23.581 0.00070917
+23.617 0.000707335
+23.653 0.000704702
+23.689 0.000701281
+23.725 0.000697083
+23.762 0.000692119
+23.798 0.0006864
+23.834 0.000679939
+23.87 0.00067275
+23.906 0.000664848
+23.942 0.000656246
+23.979 0.000646962
+24.015 0.00063701
+24.051 0.000626408
+24.087 0.000615174
+24.123 0.000603325
+24.159 0.00059088
+24.196 0.000577859
+24.232 0.000564281
+24.268 0.000550167
+24.304 0.000535536
+24.34 0.000520411
+24.376 0.000504812
+24.413 0.000488762
+24.449 0.000472282
+24.485 0.000455395
+24.521 0.000438124
+24.557 0.000420492
+24.593 0.000402523
+24.63 0.000384239
+24.666 0.000365664
+24.702 0.000346822
+24.738 0.000327738
+24.774 0.000308434
+24.81 0.000288935
+24.847 0.000269266
+24.883 0.000249449
+24.919 0.00022951
+24.955 0.000209472
+24.991 0.000189358
+25.027 0.000169194
+25.064 0.000149002
+25.1 0.000128806
+25.136 0.000108629
+25.172 8.84945e-05
+25.208 6.84252e-05
+25.244 4.84437e-05
+25.281 2.85722e-05
+25.317 8.83287e-06
+25.353 1.07528e-05
+25.389 3.01634e-05
+25.425 4.9378e-05
+25.461 6.83761e-05
+25.498 8.71376e-05
+25.534 0.000105643
+25.57 0.000123872
+25.606 0.000141808
+25.642 0.000159431
+25.678 0.000176723
+25.715 0.000193669
+25.751 0.00021025
+25.787 0.00022645
+25.823 0.000242255
+25.859 0.000257649
+25.895 0.000272618
+25.932 0.000287148
+25.968 0.000301226
+26.004 0.000314839
+26.04 0.000327976
+26.076 0.000340625
+26.112 0.000352776
+26.149 0.000364418
+26.185 0.000375543
+26.221 0.000386143
+26.257 0.000396208
+26.293 0.000405732
+26.329 0.000414708
+26.366 0.000423131
+26.402 0.000430995
+26.438 0.000438295
+26.474 0.000445029
+26.51 0.000451193
+26.546 0.000456784
+26.583 0.000461801
+26.619 0.000466242
+26.655 0.000470108
+26.691 0.000473398
diff --git a/test/capwave/markers.tex b/test/capwave/markers.tex
new file mode 100644
index 0000000..5758d74
--- /dev/null
+++ b/test/capwave/markers.tex
@@ -0,0 +1,6 @@
+Markers &
+0.3018 &
+0.0778 &
+0.0131 &
+0.0082 &
+0.00645
diff --git a/test/capwave/prosperetti b/test/capwave/prosperetti
new file mode 100644
index 0000000..f03b8a1
--- /dev/null
+++ b/test/capwave/prosperetti
@@ -0,0 +1,738 @@
+0 0.01
+0.0338878 0.0099944
+0.0677755 0.00997795
+0.101663 0.0099509
+0.135551 0.00991345
+0.169439 0.0098658
+0.203326 0.00980815
+0.237214 0.00974075
+0.271102 0.0096637
+0.30499 0.00957725
+0.338877 0.0094816
+0.372765 0.00937685
+0.406653 0.0092633
+0.440541 0.0091411
+0.474428 0.0090105
+0.508316 0.00887165
+0.542204 0.0087248
+0.576092 0.00857015
+0.60998 0.00840795
+0.643867 0.0082384
+0.677755 0.00806175
+0.711643 0.00787825
+0.74553 0.0076881
+0.779418 0.0074916
+0.813306 0.00728895
+0.847194 0.0070804
+0.881081 0.0068662
+0.914969 0.00664665
+0.948857 0.006422
+0.982745 0.0061925
+1.01663 0.0059584
+1.05052 0.00571995
+1.08441 0.00547745
+1.1183 0.0052312
+1.15218 0.00498139
+1.18607 0.00472836
+1.21996 0.00447236
+1.25385 0.00421366
+1.28773 0.00395254
+1.32162 0.00368927
+1.35551 0.00342413
+1.3894 0.00315738
+1.42329 0.00288931
+1.45717 0.00262018
+1.49106 0.00235026
+1.52495 0.00207982
+1.55884 0.00180914
+1.59272 0.00153848
+1.62661 0.00126809
+1.6605 0.000998245
+1.69439 0.000729205
+1.72828 0.000461218
+1.76216 0.000194543
+1.79605 7.05725e-05
+1.82994 0.000333881
+1.86383 0.00059514
+1.89771 0.000854105
+1.9316 0.00111055
+1.96549 0.00136424
+1.99938 0.00161495
+2.03327 0.00186245
+2.06715 0.00210654
+2.10104 0.00234698
+2.13493 0.0025836
+2.16882 0.00281616
+2.2027 0.00304448
+2.23659 0.00326838
+2.27048 0.00348767
+2.30437 0.00370215
+2.33825 0.00391166
+2.37214 0.00411604
+2.40603 0.00431513
+2.43992 0.00450876
+2.47381 0.00469679
+2.50769 0.00487908
+2.54158 0.0050555
+2.57547 0.0052259
+2.60936 0.00539015
+2.64324 0.00554815
+2.67713 0.00569985
+2.71102 0.00584505
+2.74491 0.0059837
+2.7788 0.00611575
+2.81268 0.00624105
+2.84657 0.00635955
+2.88046 0.0064712
+2.91435 0.00657595
+2.94823 0.0066737
+2.98212 0.00676445
+3.01601 0.00684815
+3.0499 0.00692475
+3.08379 0.00699425
+3.11767 0.0070566
+3.15156 0.00711185
+3.18545 0.00715995
+3.21934 0.0072009
+3.25322 0.00723475
+3.28711 0.0072615
+3.321 0.00728115
+3.35489 0.00729375
+3.38877 0.0072993
+3.42266 0.0072979
+3.45655 0.0072896
+3.49044 0.00727445
+3.52433 0.00725245
+3.55821 0.00722375
+3.5921 0.00718835
+3.62599 0.0071464
+3.65988 0.007098
+3.69376 0.00704315
+3.72765 0.006982
+3.76154 0.00691465
+3.79543 0.00684125
+3.82932 0.00676185
+3.8632 0.00667655
+3.89709 0.00658555
+3.93098 0.00648895
+3.96487 0.0063869
+3.99875 0.00627945
+4.03264 0.00616685
+4.06653 0.00604915
+4.10042 0.00592655
+4.13431 0.00579925
+4.16819 0.0056673
+4.20208 0.0055309
+4.23597 0.00539025
+4.26986 0.0052455
+4.30374 0.00509675
+4.33763 0.00494428
+4.37152 0.00478819
+4.40541 0.00462866
+4.4393 0.0044659
+4.47318 0.00430005
+4.50707 0.00413131
+4.54096 0.00395986
+4.57485 0.0037859
+4.60873 0.00360958
+4.64262 0.00343111
+4.67651 0.00325067
+4.7104 0.00306844
+4.74428 0.00288463
+4.77817 0.00269939
+4.81206 0.00251294
+4.84595 0.00232546
+4.87984 0.00213712
+4.91372 0.00194812
+4.94761 0.00175865
+4.9815 0.00156888
+5.01539 0.001379
+5.04927 0.00118921
+5.08316 0.00099966
+5.11705 0.00081055
+5.15094 0.000622055
+5.18483 0.000434348
+5.21871 0.000247603
+5.2526 6.19925e-05
+5.28649 0.000122313
+5.32038 0.000305148
+5.35426 0.000486347
+5.38815 0.00066575
+5.42204 0.000843195
+5.45593 0.00101853
+5.48982 0.00119159
+5.5237 0.00136225
+5.55759 0.00153035
+5.59148 0.00169574
+5.62537 0.00185829
+5.65925 0.00201786
+5.69314 0.00217432
+5.72703 0.00232755
+5.76092 0.00247742
+5.79481 0.00262381
+5.82869 0.00276661
+5.86258 0.00290569
+5.89647 0.00304098
+5.93036 0.00317234
+5.96424 0.0032997
+5.99813 0.00342295
+6.03202 0.003542
+6.06591 0.00365678
+6.09979 0.00376721
+6.13368 0.00387319
+6.16757 0.00397469
+6.20146 0.00407161
+6.23535 0.00416391
+6.26923 0.00425153
+6.30312 0.00433443
+6.33701 0.00441254
+6.3709 0.00448584
+6.40478 0.00455428
+6.43867 0.00461784
+6.47256 0.0046765
+6.50645 0.00473023
+6.54034 0.00477901
+6.57422 0.00482283
+6.60811 0.00486169
+6.642 0.00489558
+6.67589 0.00492451
+6.70977 0.00494849
+6.74366 0.00496753
+6.77755 0.00498164
+6.81144 0.00499086
+6.84533 0.0049952
+6.87921 0.0049947
+6.9131 0.00498938
+6.94699 0.00497929
+6.98088 0.00496449
+7.01476 0.004945
+7.04865 0.00492089
+7.08254 0.00489222
+7.11643 0.00485903
+7.15032 0.0048214
+7.1842 0.0047794
+7.21809 0.00473309
+7.25198 0.00468255
+7.28587 0.00462788
+7.31975 0.00456912
+7.35364 0.00450639
+7.38753 0.00443976
+7.42142 0.00436934
+7.4553 0.0042952
+7.48919 0.00421747
+7.52308 0.00413622
+7.55697 0.00405157
+7.59086 0.00396362
+7.62474 0.00387247
+7.65863 0.00377825
+7.69252 0.00368107
+7.72641 0.00358103
+7.76029 0.00347825
+7.79418 0.00337286
+7.82807 0.00326497
+7.86196 0.0031547
+7.89585 0.00304218
+7.92973 0.00292752
+7.96362 0.00281087
+7.99751 0.00269234
+8.0314 0.00257206
+8.06528 0.00245015
+8.09917 0.00232675
+8.13306 0.00220199
+8.16695 0.00207598
+8.20084 0.00194888
+8.23472 0.0018208
+8.26861 0.00169188
+8.3025 0.00156223
+8.33639 0.00143201
+8.37027 0.00130133
+8.40416 0.00117032
+8.43805 0.00103911
+8.47194 0.000907825
+8.50583 0.000776595
+8.53971 0.000645545
+8.5736 0.0005148
+8.60749 0.000384484
+8.64138 0.000254717
+8.67526 0.000125619
+8.70915 2.68836e-06
+8.74304 0.000130089
+8.77693 0.000256468
+8.81081 0.000381709
+8.8447 0.0005057
+8.87859 0.000628335
+8.91248 0.000749505
+8.94637 0.0008691
+8.98025 0.000987015
+9.01414 0.00110315
+9.04803 0.00121742
+9.08192 0.00132971
+9.1158 0.00143994
+9.14969 0.00154801
+9.18358 0.00165383
+9.21747 0.00175732
+9.25136 0.00185841
+9.28524 0.00195699
+9.31913 0.00205301
+9.35302 0.00214637
+9.38691 0.00223703
+9.42079 0.0023249
+9.45468 0.00240994
+9.48857 0.00249205
+9.52246 0.00257121
+9.55635 0.00264734
+9.59023 0.0027204
+9.62412 0.00279034
+9.65801 0.00285711
+9.6919 0.00292068
+9.72578 0.00298101
+9.75967 0.00303805
+9.79356 0.00309178
+9.82745 0.00314217
+9.86134 0.0031892
+9.89522 0.00323285
+9.92911 0.00327309
+9.963 0.00330992
+9.99689 0.00334332
+10.0308 0.00337328
+10.0647 0.00339981
+10.0985 0.0034229
+10.1324 0.00344254
+10.1663 0.00345875
+10.2002 0.00347155
+10.2341 0.00348093
+10.268 0.00348692
+10.3019 0.00348952
+10.3358 0.00348877
+10.3697 0.0034847
+10.4035 0.00347732
+10.4374 0.00346666
+10.4713 0.00345277
+10.5052 0.00343568
+10.5391 0.00341542
+10.573 0.00339204
+10.6069 0.00336558
+10.6408 0.0033361
+10.6746 0.00330364
+10.7085 0.00326824
+10.7424 0.00322998
+10.7763 0.00318891
+10.8102 0.00314508
+10.8441 0.00309854
+10.878 0.00304939
+10.9119 0.00299767
+10.9457 0.00294345
+10.9796 0.00288681
+11.0135 0.00282781
+11.0474 0.00276654
+11.0813 0.00270305
+11.1152 0.00263744
+11.1491 0.00256976
+11.183 0.00250013
+11.2168 0.0024286
+11.2507 0.00235527
+11.2846 0.0022802
+11.3185 0.0022035
+11.3524 0.00212524
+11.3863 0.0020455
+11.4202 0.00196438
+11.4541 0.00188197
+11.4879 0.00179836
+11.5218 0.00171363
+11.5557 0.00162786
+11.5896 0.00154115
+11.6235 0.0014536
+11.6574 0.00136529
+11.6913 0.0012763
+11.7252 0.00118674
+11.759 0.00109669
+11.7929 0.00100624
+11.8268 0.000915475
+11.8607 0.00082449
+11.8946 0.000733375
+11.9285 0.000642215
+11.9624 0.0005511
+11.9963 0.000460114
+12.0302 0.000369346
+12.064 0.000278881
+12.0979 0.000188802
+12.1318 9.9195e-05
+12.1657 1.01408e-05
+12.1996 7.8279e-05
+12.2335 0.000165984
+12.2674 0.000252894
+12.3013 0.000338934
+12.3351 0.000424025
+12.369 0.000508095
+12.4029 0.00059107
+12.4368 0.000672875
+12.4707 0.000753445
+12.5046 0.000832705
+12.5385 0.000910595
+12.5724 0.00098705
+12.6062 0.001062
+12.6401 0.00113539
+12.674 0.00120716
+12.7079 0.00127725
+12.7418 0.00134562
+12.7757 0.00141219
+12.8096 0.00147693
+12.8435 0.00153977
+12.8773 0.00160069
+12.9112 0.00165963
+12.9451 0.00171655
+12.979 0.00177141
+13.0129 0.00182417
+13.0468 0.00187481
+13.0807 0.00192326
+13.1146 0.00196953
+13.1484 0.00201357
+13.1823 0.00205536
+13.2162 0.00209487
+13.2501 0.00213209
+13.284 0.00216698
+13.3179 0.00219954
+13.3518 0.00222975
+13.3857 0.00225761
+13.4195 0.0022831
+13.4534 0.0023062
+13.4873 0.00232692
+13.5212 0.00234526
+13.5551 0.00236121
+13.589 0.00237477
+13.6229 0.00238596
+13.6568 0.00239478
+13.6907 0.00240122
+13.7245 0.00240532
+13.7584 0.00240707
+13.7923 0.00240649
+13.8262 0.00240361
+13.8601 0.00239844
+13.894 0.00239099
+13.9279 0.00238131
+13.9618 0.0023694
+13.9956 0.0023553
+14.0295 0.00233904
+14.0634 0.00232065
+14.0973 0.00230015
+14.1312 0.00227759
+14.1651 0.00225301
+14.199 0.00222643
+14.2329 0.0021979
+14.2667 0.00216747
+14.3006 0.00213517
+14.3345 0.00210105
+14.3684 0.00206515
+14.4023 0.00202753
+14.4362 0.00198822
+14.4701 0.00194728
+14.504 0.00190477
+14.5378 0.00186072
+14.5717 0.00181521
+14.6056 0.00176827
+14.6395 0.00171998
+14.6734 0.00167037
+14.7073 0.0016195
+14.7412 0.00156745
+14.7751 0.00151426
+14.8089 0.00145999
+14.8428 0.00140471
+14.8767 0.00134847
+14.9106 0.00129134
+14.9445 0.00123337
+14.9784 0.00117463
+15.0123 0.00111518
+15.0462 0.00105508
+15.08 0.000994395
+15.1139 0.00093319
+15.1478 0.00087152
+15.1817 0.00080945
+15.2156 0.000747045
+15.2495 0.00068437
+15.2834 0.00062148
+15.3173 0.00055844
+15.3512 0.00049531
+15.385 0.000432154
+15.4189 0.000369032
+15.4528 0.000306004
+15.4867 0.000243129
+15.5206 0.000180467
+15.5545 0.000118076
+15.5884 5.60155e-05
+15.6223 5.65895e-06
+15.6561 6.68905e-05
+15.69 0.000127624
+15.7239 0.000187803
+15.7578 0.000247376
+15.7917 0.000306288
+15.8256 0.00036449
+15.8595 0.000421929
+15.8934 0.000478555
+15.9272 0.00053432
+15.9611 0.00058918
+15.995 0.000643085
+16.0289 0.00069599
+16.0628 0.00074785
+16.0967 0.00079863
+16.1306 0.00084828
+16.1645 0.00089677
+16.1983 0.00094405
+16.2322 0.000990095
+16.2661 0.00103486
+16.3 0.00107832
+16.3339 0.00112043
+16.3678 0.00116118
+16.4017 0.00120052
+16.4356 0.00123843
+16.4694 0.00127489
+16.5033 0.00130986
+16.5372 0.00134333
+16.5711 0.00137528
+16.605 0.00140569
+16.6389 0.00143453
+16.6728 0.00146179
+16.7067 0.00148746
+16.7405 0.00151152
+16.7744 0.00153396
+16.8083 0.00155478
+16.8422 0.00157395
+16.8761 0.00159149
+16.91 0.00160738
+16.9439 0.0016216
+16.9778 0.00163419
+17.0117 0.00164511
+17.0455 0.00165438
+17.0794 0.00166201
+17.1133 0.00166798
+17.1472 0.00167231
+17.1811 0.00167502
+17.215 0.0016761
+17.2489 0.00167557
+17.2828 0.00167344
+17.3166 0.00166972
+17.3505 0.00166443
+17.3844 0.00165759
+17.4183 0.00164921
+17.4522 0.0016393
+17.4861 0.00162791
+17.52 0.00161503
+17.5539 0.0016007
+17.5877 0.00158494
+17.6216 0.00156777
+17.6555 0.00154923
+17.6894 0.00152934
+17.7233 0.00150812
+17.7572 0.00148562
+17.7911 0.00146185
+17.825 0.00143685
+17.8588 0.00141066
+17.8927 0.00138331
+17.9266 0.00135483
+17.9605 0.00132525
+17.9944 0.00129462
+18.0283 0.00126296
+18.0622 0.00123032
+18.0961 0.00119674
+18.1299 0.00116226
+18.1638 0.00112692
+18.1977 0.00109074
+18.2316 0.00105379
+18.2655 0.00101608
+18.2994 0.000977675
+18.3333 0.00093861
+18.3672 0.00089893
+18.401 0.00085867
+18.4349 0.00081788
+18.4688 0.0007766
+18.5027 0.000734875
+18.5366 0.00069274
+18.5705 0.00065025
+18.6044 0.00060744
+18.6383 0.00056436
+18.6722 0.000521045
+18.706 0.000477546
+18.7399 0.000433902
+18.7738 0.000390157
+18.8077 0.000346352
+18.8416 0.000302531
+18.8755 0.000258737
+18.9094 0.00021501
+18.9433 0.000171392
+18.9771 0.000127924
+19.011 8.46475e-05
+19.0449 4.16014e-05
+19.0788 1.17405e-06
+19.1127 4.36399e-05
+19.1466 8.57575e-05
+19.1805 0.00012749
+19.2144 0.000168798
+19.2482 0.000209646
+19.2821 0.000249999
+19.316 0.000289822
+19.3499 0.000329079
+19.3838 0.000367737
+19.4177 0.000405763
+19.4516 0.000443126
+19.4855 0.000479794
+19.5193 0.00051574
+19.5532 0.000550925
+19.5871 0.000585335
+19.621 0.00061893
+19.6549 0.00065169
+19.6888 0.00068359
+19.7227 0.000714605
+19.7566 0.00074471
+19.7904 0.00077388
+19.8243 0.0008021
+19.8582 0.000829345
+19.8921 0.000855595
+19.926 0.00088084
+19.9599 0.000905055
+19.9938 0.000928225
+20.0277 0.00095034
+20.0615 0.00097138
+20.0954 0.00099134
+20.1293 0.0010102
+20.1632 0.00102796
+20.1971 0.00104459
+20.231 0.00106011
+20.2649 0.0010745
+20.2988 0.00108775
+20.3327 0.00109987
+20.3665 0.00111083
+20.4004 0.00112066
+20.4343 0.00112933
+20.4682 0.00113686
+20.5021 0.00114324
+20.536 0.00114849
+20.5699 0.00115258
+20.6038 0.00115554
+20.6376 0.00115737
+20.6715 0.00115807
+20.7054 0.00115766
+20.7393 0.00115614
+20.7732 0.00115352
+20.8071 0.00114981
+20.841 0.00114502
+20.8749 0.00113916
+20.9087 0.00113225
+20.9426 0.00112431
+20.9765 0.00111534
+21.0104 0.00110537
+21.0443 0.00109439
+21.0782 0.00108245
+21.1121 0.00106956
+21.146 0.00105573
+21.1798 0.00104099
+21.2137 0.00102535
+21.2476 0.00100884
+21.2815 0.00099147
+21.3154 0.00097328
+21.3493 0.000954285
+21.3832 0.000934505
+21.4171 0.00091397
+21.4509 0.000892705
+21.4848 0.000870735
+21.5187 0.00084808
+21.5526 0.00082478
+21.5865 0.00080085
+21.6204 0.00077632
+21.6543 0.00075122
+21.6882 0.00072558
+21.722 0.000699425
+21.7559 0.000672785
+21.7898 0.000645685
+21.8237 0.00061816
+21.8576 0.00059024
+21.8915 0.00056195
+21.9254 0.000533325
+21.9593 0.00050439
+21.9931 0.000475175
+22.027 0.000445714
+22.0609 0.000416034
+22.0948 0.000386166
+22.1287 0.00035614
+22.1626 0.000325985
+22.1965 0.000295733
+22.2304 0.000265412
+22.2643 0.000235051
+22.2981 0.000204681
+22.332 0.000174331
+22.3659 0.000144028
+22.3998 0.000113804
+22.4337 8.3685e-05
+22.4676 5.37e-05
+22.5015 2.38765e-05
+22.5354 5.7578e-06
+22.5692 3.51759e-05
+22.6031 6.43515e-05
+22.637 9.32575e-05
+22.6709 0.000121869
+22.7048 0.00015016
+22.7387 0.000178105
+22.7726 0.000205683
+22.8065 0.000232865
+22.8403 0.000259632
+22.8742 0.00028596
+22.9081 0.000311826
+22.942 0.000337209
+22.9759 0.000362089
+23.0098 0.000386445
+23.0437 0.000410257
+23.0776 0.000433507
+23.1114 0.000456176
+23.1453 0.000478245
+23.1792 0.000499701
+23.2131 0.000520525
+23.247 0.0005407
+23.2809 0.000560215
+23.3148 0.000579055
+23.3487 0.000597205
+23.3825 0.000614655
+23.4164 0.00063139
+23.4503 0.0006474
+23.4842 0.00066268
+23.5181 0.000677215
+23.552 0.000690995
+23.5859 0.000704015
+23.6198 0.00071627
+23.6536 0.00072775
+23.6875 0.000738455
+23.7214 0.00074837
+23.7553 0.000757505
+23.7892 0.000765845
+23.8231 0.00077339
+23.857 0.000780145
+23.8909 0.0007861
+23.9248 0.00079126
+23.9586 0.00079563
+23.9925 0.000799205
+24.0264 0.000801985
+24.0603 0.000803985
+24.0942 0.000805195
+24.1281 0.000805625
+24.162 0.00080528
+24.1959 0.00080417
+24.2297 0.000802295
+24.2636 0.00079967
+24.2975 0.00079629
+24.3314 0.00079218
+24.3653 0.000787335
+24.3992 0.00078177
+24.4331 0.0007755
+24.467 0.00076853
+24.5008 0.000760875
+24.5347 0.000752545
+24.5686 0.000743555
+24.6025 0.00073392
+24.6364 0.000723645
+24.6703 0.000712755
+24.7042 0.00070126
+24.7381 0.000689175
+24.7719 0.000676515
+24.8058 0.0006633
+24.8397 0.000649545
+24.8736 0.000635265
+24.9075 0.00062048
+24.9414 0.000605205
+24.9753 0.00058946
diff --git a/test/capwave/prost.tex b/test/capwave/prost.tex
new file mode 100644
index 0000000..347a4d9
--- /dev/null
+++ b/test/capwave/prost.tex
@@ -0,0 +1,5 @@
+PROST &
+0.2960 &
+0.0818 &
+0.0069 &
+0.0018
diff --git a/test/capwave/surfer.tex b/test/capwave/surfer.tex
new file mode 100644
index 0000000..cb39cdb
--- /dev/null
+++ b/test/capwave/surfer.tex
@@ -0,0 +1,6 @@
+Surfer &
+- &
+- &
+0.1168 &
+0.0132 &
+0.007
diff --git a/test/channel/channel.gfs b/test/channel/channel.gfs
new file mode 100644
index 0000000..43517ad
--- /dev/null
+++ b/test/channel/channel.gfs
@@ -0,0 +1,60 @@
+# Title: Flow through a divergent channel
+#
+# Description:
+#
+# A test case initially presented by Almgren et al \cite{almgren97}.
+# The Euler equations are solved in a divergent channel for a unit
+# inflow velocity on the left boundary and outflow on the right
+# boundary.
+#
+# Tables \ref{channel-x} and \ref{channel-y} illustrate the errors and
+# convergence orders obtained for both components of the velocity when
+# the resolution varies. Richardson extrapolation is used.  The errors
+# are computed either on the whole domain (All cells) or on the cells
+# whose parents at level 5 are entirely contained in the fluid (Full
+# 128 cells).
+#
+# Close to second-order convergence is obtained in the bulk of the
+# fluid, reducing to first-order close to the boundaries. The errors
+# are small in all cases (with a maximum of .5\%) and comparable to
+# that obtained by Almgren et al using a different discretisation.
+#
+# \input{convergence.tex}
+#
+# Author: St\'ephane Popinet
+# Command: sh channel.sh channel.gfs
+# Version: 1.1.0
+# Required files: channel.sh orderU.ref orderfU.ref orderV.ref orderfV.ref
+# Running time: 3 minutes
+# Generated files: convergence.tex
+#
+4 3 GfsSimulation GfsBox GfsGEdge {} {
+    Time { end = 1 }
+    AdvectionParams { cfl = 0.9 }
+    ProjectionParams { tolerance = 1e-6 }
+    ApproxProjectionParams { tolerance = 1e-6 }
+    Refine LEVEL
+    Global {
+        double channel (double x) {
+            double y1 = 0.2/4.;
+            double y2 = 1e-6/4.;
+            
+            return x <= -0.25 ? y1 : 
+                   x < 0.25 ? y2 + 0.5*(y1 - y2)*(1. + cos (2.*M_PI*(x + 0.25))) : 
+                   y2;
+        }
+    }
+    Solid (0.125 - channel (x) - y) { scale = 4 tx = 1.5 }
+    Solid (y + 0.125 - channel (x)) { scale = 4 tx = 1.5 }
+    Init {} { U = 1 }
+    OutputSimulation { start = end } sim-LEVEL {
+        variables = U,V,P
+    }
+}
+GfsBox { left = Boundary { BcDirichlet U 1 } }
+GfsBox {}
+GfsBox {}
+GfsBox { right = BoundaryOutflow }
+1 2 right
+2 3 right
+3 4 right
diff --git a/test/channel/channel.sh b/test/channel/channel.sh
new file mode 100644
index 0000000..736ef15
--- /dev/null
+++ b/test/channel/channel.sh
@@ -0,0 +1,83 @@
+if ! $donotrun; then
+    shapes channel | transform --revert --scale 4 --tx 1.5 > channel.gts
+    for level in 5 6 7; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+           gerris2D -; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+for v in U V; do
+    rm -f order$v orderf$v
+    for level in 5 6; do
+	level1=`expr $level + 1`
+	echo -n "$level " >> order$v
+	if gfscompare2D -v sim-$level sim-$level1 $v 2>&1 | \
+	    awk '{if ($1 == "total") print $4 " " $6 " " $8;}' >> order$v; then :
+	else
+	    exit 1
+	fi
+	echo -n "$level " >> orderf$v
+	if gfscompare2D -f 5 -v sim-$level sim-$level1 $v 2>&1 | \
+	    awk '{if ($1 == "total") print $4 " " $6 " " $8;}' >> orderf$v; then :
+	else
+	    exit 1
+	fi
+    done
+done
+
+if cat <<EOF | python > convergence.tex; then :
+from check import *
+from sys import *
+from math import *
+
+for component,variable in [('x','U'),('y','V')]:
+  print r"""\begin{table}[htbp]
+  \caption{"""
+  print r"\label{channel-" + component + "}"
+  print r"Errors and convergence rates for the \$"+component+r"\$-component of the velocity.}"
+  print r"""\begin{center}
+  \begin{tabular}{||l|c|c|c||c|c|c||} \hline
+           & \multicolumn{3}{c||}{All cells} & \multicolumn{3}{c||}{Full 128 cells} \\\ \hline
+           & 128-256  & Rate & 256-512  & 128-256  & Rate & 256-512  \\\ \hline"""
+
+  for i,name in [(2,r"\$L_1\$"),(3,r"\$L_2\$"),(4,r"\$L_\infty\$")]:
+    a=Curve('order'+variable,1,i)
+    b=Curve('orderf'+variable,1,i)
+    print name,
+    print "& %.2e & %4.2f & %.2e & %.2e & %4.2f & %.2e" % (\
+    a.l[0][1], log(a.l[0][1]/a.l[1][1])/log(2.), a.l[1][1], \
+    b.l[0][1], log(b.l[0][1]/b.l[1][1])/log(2.), b.l[1][1]),
+    print r"\\\"
+
+    a=Curve('order'+variable+'.ref',1,i)
+    b=Curve('orderf'+variable+'.ref',1,i)
+    print "& {\color{blue}%.2e} & {\color{blue}%4.2f} & {\color{blue}%.2e} & {\color{blue}%.2e} & {\color{blue}%4.2f} & {\color{blue}%.2e}" % (\
+    a.l[0][1], log(a.l[0][1]/a.l[1][1])/log(2.), a.l[1][1], \
+    b.l[0][1], log(b.l[0][1]/b.l[1][1])/log(2.), b.l[1][1]),
+    print r"\\\"
+
+  print r"\hline"
+  print r"""\end{tabular}
+  \end{center}
+  \end{table}"""
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+
+for f in ['orderU','orderV','orderfU','orderfV']:
+   if (Curve(f,1,2) - Curve(f+'.ref',1,2)).max() > 1e-6 or\
+      (Curve(f,1,3) - Curve(f+'.ref',1,3)).max() > 1e-6 or\
+      (Curve(f,1,4) - Curve(f+'.ref',1,4)).max() > 1e-6:
+      exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/channel/orderU.ref b/test/channel/orderU.ref
new file mode 100644
index 0000000..28fcf6f
--- /dev/null
+++ b/test/channel/orderU.ref
@@ -0,0 +1,2 @@
+5 1.176e-04 2.889e-04 2.334e-03
+6 5.092e-05 1.544e-04 1.618e-03
diff --git a/test/channel/orderV.ref b/test/channel/orderV.ref
new file mode 100644
index 0000000..0e79301
--- /dev/null
+++ b/test/channel/orderV.ref
@@ -0,0 +1,2 @@
+5 1.728e-04 5.273e-04 4.552e-03
+6 4.903e-05 1.914e-04 2.427e-03
diff --git a/test/channel/orderfU.ref b/test/channel/orderfU.ref
new file mode 100644
index 0000000..9008f1d
--- /dev/null
+++ b/test/channel/orderfU.ref
@@ -0,0 +1,2 @@
+5 1.021e-04 2.578e-04 2.177e-03
+6 3.737e-05 1.128e-04 1.362e-03
diff --git a/test/channel/orderfV.ref b/test/channel/orderfV.ref
new file mode 100644
index 0000000..59385fc
--- /dev/null
+++ b/test/channel/orderfV.ref
@@ -0,0 +1,2 @@
+5 1.537e-04 4.966e-04 4.552e-03
+6 3.415e-05 1.428e-04 2.282e-03
diff --git a/test/check.py b/test/check.py
new file mode 100644
index 0000000..79a5cbd
--- /dev/null
+++ b/test/check.py
@@ -0,0 +1,69 @@
+from sys import *
+from math import *
+
+class Curve:
+	def read(self,file,x,y):
+		line = file.readline()
+		while line:
+			record = line.split()
+			if record[0] != "#":
+				self.l.append((float(record[x-1]),float(record[y-1])))
+			line = file.readline()
+	def __init__(self,f=None,x=1,y=2):
+		self.l = []
+		if f:
+			self.read(open(f,'r'),x,y)
+	def value(self,x):
+		l,u = 0,len(self.l)-1
+		if u == l:
+			return self.l[u][1]
+		while u - l > 1:
+			i = (u + l)/2
+			if self.l[i][0] > x:
+				u = i
+			else:
+				l = i
+		x0,x1,y0,y1 = self.l[l][0],self.l[u][0],self.l[l][1],self.l[u][1]
+		return y0 + (x - x0)/(x1 - x0)*(y1 - y0)
+	def __sub__(self,other):
+		c = Curve()
+		if len(self.l) < len(other.l):
+			for p in self.l:
+				c.l.append((p[0], p[1] - other.value(p[0])))
+		else:
+			for p in other.l:
+				c.l.append((p[0], self.value(p[0]) - p[1]))
+		return c
+	def sum(self,f=lambda x: x):
+		s = 0.
+		p1 = None
+		for p in self.l:
+			if p1:
+				s += (p[0] - p1[0])*f((p[1] + p1[1])/2.)
+			p1 = p
+		return s
+	def max(self,f=lambda x: x):
+		m = None
+		for p in self.l:
+			v = f(p[1])
+			if not m or v > m:
+				m = v
+		return m
+	def min(self,f=lambda x: x):
+		m = None
+		for p in self.l:
+			v = f(p[1])
+			if not m or v < m:
+				m = v
+		return m
+	def mean(self):
+		return self.sum()/self.sum(lambda x: 1.)
+	def norm1(self):
+		return self.sum(lambda x: abs(x))/self.sum(lambda x: 1.)
+	def norm2(self):
+		return sqrt(self.sum(lambda x: x*x)/self.sum(lambda x: 1.))
+	def normi(self):
+		return self.max(lambda x: abs(x))
+	def write(self):
+		for p in self.l:
+			print p[0],p[1]
diff --git a/test/circle/circle.gfs b/test/circle/circle.gfs
new file mode 100644
index 0000000..2481914
--- /dev/null
+++ b/test/circle/circle.gfs
@@ -0,0 +1,76 @@
+# Title: Convergence of the Poisson solver with solid boundaries
+#
+# Description:
+#
+# Another of the test cases presented in Popinet \cite{popinet2003}. A
+# circular solid boundary of radius 0.25 is embedded in the
+# domain. The same right-hand-side is used.
+# 
+# This time the problem does not have an analytical solution and we
+# use Richardson extrapolation to estimate the error for a given
+# resolution.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Solution of the Poisson equation.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh circle.sh circle.gfs
+# Version: 1.1.0
+# Required files: circle.sh res-7.ref error.ref order.ref solution.gfv
+# Generated files: residual.eps rate.eps error.eps order.eps solution.eps
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+  Time { iend = 10 }
+  Refine LEVEL
+  Solid (ellipse (0, 0, 0.25, 0.25))
+  ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 erelax = 2 }
+  Init {} {
+    Div = {
+      int k = 3, l = 3;
+      return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+    }
+  }
+  OutputTime { istep = 1 } {
+    awk '{print n++, $8}' > time
+  }
+  OutputProjectionStats { istep = 1 } {
+    awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+  }
+  OutputSimulation { start = end } sim-LEVEL { variables = P }
+}
+GfsBox {}
diff --git a/test/circle/circle.sh b/test/circle/circle.sh
new file mode 100644
index 0000000..41d2b61
--- /dev/null
+++ b/test/circle/circle.sh
@@ -0,0 +1,93 @@
+if ! $donotrun; then
+    for level in 3 4 5 6 7 8 9; do
+	if ( sed "s/LEVEL/$level/g" < $1 | gerris2D - ) && join time proj > res-$level; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+rm -f error
+for level in 3 4 5 6 7 8; do
+    next=`expr $level + 1`
+    echo -n "$level " >> error
+    if gfscompare2D -C -c -v sim-$level sim-$next P 2>&1 | \
+	awk '{if ($1 == "total") print $4 " " $6 " " $8;}' >> error; then :
+    else
+	exit 1
+    fi
+done
+
+if echo "Save solution.eps { format = EPS line_width = 0.25}" | gfsview-batch2D sim-9 solution.gfv; then :
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n1[n] = $2; n2[n] = $3; ni[n++] = $4;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n1[i-1]/n1[i])/log(2.) " " log(n2[i-1]/n2[i])/log(2.) " " log(ni[i-1]/ni[i])/log(2.);
+}' < error > order; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'residual.eps'
+    set xlabel 'CPU time'
+    set ylabel 'Maximum residual'
+    set logscale y
+    plot 'res-7.ref' u 2:3 t 'ref' w lp, 'res-7' u 2:3 t '' w lp
+    set output 'rate.eps'
+    set xlabel 'V-cycle'
+    set ylabel 'Cumulative residual reduction factor'
+    unset logscale
+    plot 'res-7.ref' u 1:4 t 'ref' w lp, 'res-7' u 1:4 t '' w lp
+    set output 'error.eps'
+    set xlabel 'Level'
+    set ylabel 'Error norms'
+    set key
+    set logscale y
+    plot 'error.ref' u 1:2 t '1 (ref)' w lp, \
+         'error.ref' u 1:3 t '2 (ref)' w lp, \
+         'error.ref' u 1:4 t 'max (ref)' w lp, \
+         'error' u 1:2 t '1' w lp, \
+         'error' u 1:3 t '2' w lp, \
+         'error' u 1:4 t 'max' w lp
+    set output 'order.eps'
+    set xlabel 'Level'
+    set ylabel 'Order'
+    set key
+    unset logscale
+    set xtics 0,1
+    set ytics 0,1
+    set grid
+    plot [][0:3] 'order.ref' u 1:2 t '1 (ref)' w lp, \
+                 'order.ref' u 1:3 t '2 (ref)' w lp, \
+                 'order.ref' u 1:4 t 'max (ref)' w lp, \
+                 'order' u 1:2 t '1' w lp, \
+                 'order' u 1:3 t '2' w lp, \
+                 'order' u 1:4 t 'max' w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+c = Curve()
+for p in Curve('res-7.ref',2,3).l:
+    c.l.append((p[0]+0.1, p[1]))
+if (Curve('res-7',2,3) - c).max() > 1e-8 or\
+   (Curve('error',1,4) - Curve('error.ref',1,4)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/circle/error.ref b/test/circle/error.ref
new file mode 100644
index 0000000..dfc1e3b
--- /dev/null
+++ b/test/circle/error.ref
@@ -0,0 +1,6 @@
+3 7.983e-02 1.068e-01 2.972e-01
+4 1.773e-02 2.227e-02 4.846e-02
+5 4.495e-03 5.567e-03 1.339e-02
+6 1.088e-03 1.356e-03 3.952e-03
+7 2.809e-04 3.504e-04 1.802e-03
+8 6.908e-05 8.573e-05 3.554e-04
diff --git a/test/circle/order.ref b/test/circle/order.ref
new file mode 100644
index 0000000..3d65837
--- /dev/null
+++ b/test/circle/order.ref
@@ -0,0 +1,5 @@
+4 2.17074 2.26174 2.61657
+5 1.9798 2.00013 1.85564
+6 2.04664 2.03754 1.7605
+7 1.95355 1.95228 1.13298
+8 2.02372 2.03113 2.34208
diff --git a/test/circle/refined/error.ref b/test/circle/refined/error.ref
new file mode 100644
index 0000000..3478a9a
--- /dev/null
+++ b/test/circle/refined/error.ref
@@ -0,0 +1,6 @@
+3 1.031e-01 1.423e-01 3.652e-01
+4 2.943e-02 3.575e-02 7.316e-02
+5 6.323e-03 7.547e-03 1.639e-02
+6 1.472e-03 1.768e-03 3.912e-03
+7 3.350e-04 4.078e-04 9.345e-04
+8 8.133e-05 9.961e-05 3.329e-04
diff --git a/test/circle/refined/order.ref b/test/circle/refined/order.ref
new file mode 100644
index 0000000..d164206
--- /dev/null
+++ b/test/circle/refined/order.ref
@@ -0,0 +1,5 @@
+4 1.80868 1.99292 2.31956
+5 2.21861 2.24397 2.15824
+6 2.10283 2.09378 2.06684
+7 2.13554 2.11618 2.06564
+8 2.0423 2.0335 1.48911
diff --git a/test/circle/refined/refined.gfs b/test/circle/refined/refined.gfs
new file mode 100644
index 0000000..bf71863
--- /dev/null
+++ b/test/circle/refined/refined.gfs
@@ -0,0 +1,77 @@
+# Title: Star-shaped solid boundary with refinement
+#
+# Description:
+#
+# Same as the star test but with two levels of refinement added near 
+# the solid boundary.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Solution of the Poisson equation.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../circle.sh refined.gfs
+# Version: 1.1.2
+# Required files: res-7.ref error.ref order.ref solution.gfv
+# Generated files: residual.eps rate.eps error.eps order.eps solution.eps
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+    Time { iend = 10 }
+    Refine LEVEL
+    RefineSolid (LEVEL + 2)
+    Solid ({
+            double dr = 0.1;
+            double theta = atan2 (y, x);
+            double radius = 0.79*(0.45 - dr + dr*cos (6.*theta));
+            return x*x + y*y - radius*radius;
+          })
+    ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 }
+    Init {} {
+        Div = {
+            int k = 3, l = 3;
+            return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+        }
+    }
+    OutputTime { istep = 1 } {
+        awk '{print n++, $8}' > time
+    }
+    OutputProjectionStats { istep = 1 } {
+        awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+    }
+    OutputSimulation { start = end } sim-LEVEL { variables = P }
+}
+GfsBox {}
diff --git a/test/circle/refined/res-7.ref b/test/circle/refined/res-7.ref
new file mode 100644
index 0000000..d9f4be2
--- /dev/null
+++ b/test/circle/refined/res-7.ref
@@ -0,0 +1,11 @@
+0 0.00000000 1.775e+02 0
+1 0.13000000 7.967e+01 2.2
+2 0.24000000 3.404e+01 2.3
+3 0.36000000 4.312e+00 3.5
+4 0.47000000 1.104e+00 3.6
+5 0.58000000 3.463e-01 3.5
+6 0.70000000 1.017e-01 3.5
+7 0.81000000 2.778e-02 3.5
+8 0.92000000 8.372e-03 3.5
+9 1.03000000 2.247e-03 3.5
+10 1.14000000 6.869e-04 3.5
diff --git a/test/circle/refined/solution.gfv b/test/circle/refined/solution.gfv
new file mode 100644
index 0000000..26884cc
--- /dev/null
+++ b/test/circle/refined/solution.gfv
@@ -0,0 +1,38 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 30
+}
diff --git a/test/circle/res-7.ref b/test/circle/res-7.ref
new file mode 100644
index 0000000..67ef393
--- /dev/null
+++ b/test/circle/res-7.ref
@@ -0,0 +1,11 @@
+0 0.00000000 1.775e+02 0
+1 0.07000000 4.867e+00 36
+2 0.13000000 1.526e-01 34
+3 0.19000000 5.844e-03 31
+4 0.24000000 2.190e-04 30
+5 0.30000000 7.283e-06 30
+6 0.36000000 2.330e-07 30
+7 0.42000000 6.724e-09 31
+8 0.48000000 2.837e-10 30
+9 0.54000000 1.958e-11 28
+10 0.60000000 1.640e-11 20
diff --git a/test/circle/solution.gfv b/test/circle/solution.gfv
new file mode 100644
index 0000000..26884cc
--- /dev/null
+++ b/test/circle/solution.gfv
@@ -0,0 +1,38 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 30
+}
diff --git a/test/circle/star/error.ref b/test/circle/star/error.ref
new file mode 100644
index 0000000..ce48330
--- /dev/null
+++ b/test/circle/star/error.ref
@@ -0,0 +1,6 @@
+3 1.467e-01 1.691e-01 2.966e-01
+4 1.987e-02 2.465e-02 5.349e-02
+5 6.993e-03 8.183e-03 1.644e-02
+6 1.120e-03 1.413e-03 3.203e-03
+7 2.713e-04 3.451e-04 1.543e-03
+8 1.184e-04 1.382e-04 5.969e-04
diff --git a/test/circle/star/order.ref b/test/circle/star/order.ref
new file mode 100644
index 0000000..99a085b
--- /dev/null
+++ b/test/circle/star/order.ref
@@ -0,0 +1,5 @@
+4 2.88421 2.77822 2.47118
+5 1.50661 1.59089 1.70206
+6 2.64241 2.53387 2.35971
+7 2.04554 2.03368 1.05369
+8 1.19622 1.32026 1.37018
diff --git a/test/circle/star/res-7.ref b/test/circle/star/res-7.ref
new file mode 100644
index 0000000..f6ed7da
--- /dev/null
+++ b/test/circle/star/res-7.ref
@@ -0,0 +1,11 @@
+0 0.00000000 1.775e+02 0
+1 0.07000000 2.218e+01 8
+2 0.13000000 7.922e-01 15
+3 0.19000000 2.020e-02 21
+4 0.26000000 9.981e-04 21
+5 0.32000000 3.120e-05 22
+6 0.38000000 1.313e-06 23
+7 0.44000000 6.383e-08 22
+8 0.50000000 2.329e-09 23
+9 0.57000000 1.308e-10 22
+10 0.62000000 2.316e-11 19
diff --git a/test/circle/star/solution.gfv b/test/circle/star/solution.gfv
new file mode 100644
index 0000000..26884cc
--- /dev/null
+++ b/test/circle/star/solution.gfv
@@ -0,0 +1,38 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 30
+}
diff --git a/test/circle/star/star.gfs b/test/circle/star/star.gfs
new file mode 100644
index 0000000..4a21b33
--- /dev/null
+++ b/test/circle/star/star.gfs
@@ -0,0 +1,83 @@
+# Title: Star-shaped solid boundary
+#
+# Description:
+#
+# A similar but more difficult test using a star-shaped solid boundary
+# defined in polar coordinates as
+# $$
+# r(\theta)=0.2765+0.079\cos(6\theta)
+# $$
+#
+# The convergence rate is smaller because the shape of the boundary is
+# not represented properly on the coarsest levels of the multigrid
+# hierarchy.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Solution of the Poisson equation.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../circle.sh star.gfs
+# Version: 1.1.0
+# Required files: res-7.ref error.ref order.ref solution.gfv
+# Generated files: residual.eps rate.eps error.eps order.eps solution.eps
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+    Time { iend = 10 }
+    Refine LEVEL
+    Solid ({
+            double dr = 0.1;
+            double theta = atan2 (y, x);
+            double radius = 0.79*(0.45 - dr + dr*cos (6.*theta));
+            return x*x + y*y - radius*radius;
+          })
+    ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 erelax = 2 }
+    Init {} {
+        Div = {
+            int k = 3, l = 3;
+            return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+        }
+    }
+    OutputTime { istep = 1 } {
+        awk '{print n++, $8}' > time
+    }
+    OutputProjectionStats { istep = 1 } {
+        awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+    }
+    OutputSimulation { start = end } sim-LEVEL { variables = P }
+}
+GfsBox {}
diff --git a/test/circle/thin/error.ref b/test/circle/thin/error.ref
new file mode 100644
index 0000000..6ba8e5e
--- /dev/null
+++ b/test/circle/thin/error.ref
@@ -0,0 +1,6 @@
+3 1.577e-01 1.943e-01 4.335e-01
+4 6.417e-02 7.586e-02 2.048e-01
+5 2.960e-02 3.379e-02 1.364e-01
+6 1.426e-02 1.605e-02 9.463e-02
+7 7.001e-03 7.844e-03 6.646e-02
+8 3.468e-03 3.880e-03 4.687e-02
diff --git a/test/circle/thin/order.ref b/test/circle/thin/order.ref
new file mode 100644
index 0000000..59a91d2
--- /dev/null
+++ b/test/circle/thin/order.ref
@@ -0,0 +1,5 @@
+4 1.29721 1.35687 1.08182
+5 1.1163 1.16674 0.586372
+6 1.05362 1.07402 0.527474
+7 1.02634 1.03291 0.509811
+8 1.01346 1.01553 0.503821
diff --git a/test/circle/thin/res-7.ref b/test/circle/thin/res-7.ref
new file mode 100644
index 0000000..19c7d9f
--- /dev/null
+++ b/test/circle/thin/res-7.ref
@@ -0,0 +1,10 @@
+1 0.4 2.895e+02 0.61
+2 0.73 8.132e+01 1.5
+3 1.07 2.256e+01 2
+4 1.39 6.258e+00 2.3
+5 1.7 1.736e+00 2.5
+6 2.03 4.814e-01 2.7
+7 2.36 1.335e-01 2.8
+8 2.68 3.703e-02 2.9
+9 3.05 1.027e-02 3
+10 3.36 2.848e-03 3
diff --git a/test/circle/thin/solution.gfv b/test/circle/thin/solution.gfv
new file mode 100644
index 0000000..63bf42e
--- /dev/null
+++ b/test/circle/thin/solution.gfv
@@ -0,0 +1,50 @@
+# GfsView 2D
+View {
+  tx = -0.591968 ty = 0.496337
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 37.9885
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Solid {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 30
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+}
diff --git a/test/circle/thin/thin.gfs b/test/circle/thin/thin.gfs
new file mode 100644
index 0000000..627d78a
--- /dev/null
+++ b/test/circle/thin/thin.gfs
@@ -0,0 +1,78 @@
+# Title: Thin wall at box boundary
+#
+# Description:
+#
+# Boxes are used to setup a similar problem but with an infinitely
+# thin wall.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Solution of the Poisson equation.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../circle.sh thin.gfs
+# Version: 0.8.0
+# Required files: res-7.ref error.ref order.ref solution.gfv
+# Generated files: residual.eps rate.eps error.eps order.eps solution.eps
+#
+4 3 GfsPoisson GfsBox GfsGEdge {} {
+  Time { iend = 10 }
+  Refine LEVEL
+  ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 erelax = 2 }
+  Init {} {
+    Div = {
+      int k = 3, l = 3;
+      x = (x - 0.5)/2.;
+      y = (y + 0.5)/2.;
+      return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+    }
+  }
+  OutputTime { istep = 1 } {
+    awk '{print n++, $8}' > time
+  }
+  OutputProjectionStats { istep = 1 } {
+    awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+  }
+  OutputSimulation { start = end } sim-LEVEL { variables = P }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 2 right
+2 3 bottom
+3 4 left
diff --git a/test/cosine/cosine.gfs b/test/cosine/cosine.gfs
new file mode 100644
index 0000000..127de78
--- /dev/null
+++ b/test/cosine/cosine.gfs
@@ -0,0 +1,184 @@
+# Title: Advection of a cosine bell around the sphere
+#
+# Description:
+#
+# This test case was suggested by Williamson et
+# al. \cite{williamson92} (Problem \#1). A "cosine bell" initial
+# concentration is given by
+# $$
+# h(\lambda,\theta)=(h_0/2)(1+\cos(\pi r/R))
+# $$
+# if $r<R$ and 0 otherwise, with $R=1/3$ and
+# $$
+# r=\arccos[\sin\theta_c\sin\theta+\cos\theta_c\cos\theta\cos(\lambda-\lambda_c)]
+# $$
+# the great circle distance between longitude, latitude
+# $(\lambda,\theta)$ and the center initially taken as
+# $(\lambda_c,\theta_c)=(3\pi/2,0)$.
+#
+# The advection velocity field corresponds to solid-body rotation at an
+# angle $\alpha$ to the polar axis of the spherical coordinate
+# system. It is given by the streamfunction
+# $$
+# \psi=-u_0(\sin\theta\cos\alpha-\cos\lambda\cos\theta\sin\alpha)
+# $$
+#
+# The cosine bell field is rotated once around the sphere and should
+# come back exactly to its original position. The difference between
+# the initial and final fields is a measure of the accuracy of the
+# advection scheme coupled with the spherical coordinate mapping (the
+# "conformal expanded spherical cube" metric in our case).
+#
+# For the "spherical cube" metric, two angles are considered: 45
+# degrees which rotates the cosine bell above four of the eight "poles"
+# of the mapping and 90 degrees which avoids the poles entirely. Mass
+# is conserved to within machine accuracy in either case.
+#
+# The mesh is adapted dynamically according to the gradient of tracer
+# concentration.
+#
+# \begin{figure}[htbp] 
+# \caption{\label{solution45}Tracer field after one rotation around the
+# sphere with $\alpha=45^\circ$ (red). Reference solution
+# (green). Zero level contour line (blue). Equivalent static
+# resolutions (a) $16\times 16\times 6$. (b) $32\times 32\times
+# 6$. (c) $64\times 64\times 6$. (d) $128\times 128\times 6$.}
+# \begin{center}
+# \begin{tabular}{cc}
+# (a) \includegraphics[width=0.45\hsize]{isolines-4-45.eps} &
+# (b) \includegraphics[width=0.45\hsize]{isolines-5-45.eps} \\
+# (c) \includegraphics[width=0.45\hsize]{isolines-6-45.eps} &
+# (d) \includegraphics[width=0.45\hsize]{isolines-7-45.eps}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp] 
+# \caption{\label{solution90}Tracer field after one rotation around the
+# sphere with $\alpha=90^\circ$ (red). Reference solution
+# (green). Zero level contour line (blue). Equivalent static
+# resolutions (a) $16\times 16\times 6$. (b) $32\times 32\times
+# 6$. (c) $64\times 64\times 6$. (d) $128\times 128\times 6$.}
+# \begin{center}
+# \begin{tabular}{cc}
+# (a) \includegraphics[width=0.45\hsize]{isolines-4-90.eps} &
+# (b) \includegraphics[width=0.45\hsize]{isolines-5-90.eps} \\
+# (c) \includegraphics[width=0.45\hsize]{isolines-6-90.eps} &
+# (d) \includegraphics[width=0.45\hsize]{isolines-7-90.eps}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp] 
+# \caption{\label{error}Relative error norms (as defined in
+# \cite{williamson92}) as functions of spatial resolution. The results
+# of Rossmanith \cite{rossmanith2006} using a gnomonic spherical cube
+# metric and a different 2nd-order advection scheme are also
+# reproduced for comparison. (a) $\alpha=45^\circ$. (b)
+# $\alpha=90^\circ$.}
+# \begin{center}
+# \begin{tabular}{c}
+# (a) \includegraphics[width=0.7\hsize]{order-45.eps} \\
+# (b) \includegraphics[width=0.7\hsize]{order-90.eps}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh cosine.sh
+# Version: 091029
+# Required files: cosine.sh isolines.gfv reference.gfv zero.gfv error-45.ref error-90.ref rossmanith45 rossmanith90
+# Running time: 6 minutes
+# Generated files: isolines-4-45.eps  isolines-5-90.eps  isolines-7-45.eps  order-90.eps isolines-4-90.eps  isolines-6-45.eps  isolines-7-90.eps isolines-5-45.eps  isolines-6-90.eps  order-45.eps
+#
+Define U0 (2.*M_PI)
+
+6 12 GfsAdvection GfsBox GfsGEdge {} {
+  PhysicalParams { L = 2.*M_PI/4. }
+  MetricCubed M LEVEL
+  Time { end = 1 }
+  Refine LEVEL
+  VariableTracer T { 
+      gradient = gfs_center_gradient 
+      cfl = 1
+  }
+  Global {
+      #define DTR (M_PI/180.)
+      double bell (double x, double y, double t) {
+	  double h0 = 1.;
+	  double R = 1./3.;
+	  double lc = 3.*M_PI/2. + U0*t, tc = 0.;
+	  x *= DTR; y *= DTR;
+	  double r = acos (sin(tc)*sin(y) + cos (tc)*cos (y)*cos (x - lc));
+	  return r >= R ? 0. : (h0/2.)*(1. + cos (M_PI*r/R));
+      }
+  }
+  Init {} { T = bell(x,y,0) }
+  VariableStreamFunction Psi -U0*(sin (y*DTR)*cos (DTR*ALPHA) - cos (x*DTR)*cos (y*DTR)*sin (DTR*ALPHA))
+  AdaptGradient { istep = 1 } { cmax = 1e-4 maxlevel = LEVEL } T
+  OutputTime { istep = 10 } stderr
+#  OutputSimulation { istep = 10 } stdout
+  OutputSimulation { start = end } end-LEVEL-ALPHA.gfs
+  OutputErrorNorm { istep = 1 } { awk '{ print LEVEL,$3,$5,$7,$9}' > error-LEVEL-ALPHA } { v = T } {
+      s = bell(x,y,t)
+      v = E
+      relative = 1
+  }
+  OutputScalarSum { istep = 1 } t-LEVEL-ALPHA { v = T }
+  OutputScalarSum { istep = 1 } area-LEVEL-ALPHA { v = 1 }
+  EventScript { start = end } {
+      ( cat isolines.gfv
+        echo "Save isolines.gnu { format = Gnuplot }"
+        echo "Clear"
+        cat reference.gfv
+        echo "Save reference.gnu { format = Gnuplot }"
+	echo "Clear"
+        cat zero.gfv
+        echo "Save zero.gnu { format = Gnuplot }"
+      ) | gfsview-batch2D end-LEVEL-ALPHA.gfs
+      cat <<EOF | gnuplot
+        set term postscript eps lw 2 18 color
+        set output 'isolines-LEVEL-ALPHA.eps'
+        set size ratio -1
+        set xlabel 'Longitude'
+        set ylabel 'Latitude'
+        unset key
+        plot [-120:-60][-30:30]'isolines.gnu' w l, 'reference.gnu' w l, 'zero.gnu' w l
+EOF
+      fixbb isolines-LEVEL-ALPHA.eps
+      rm -f isolines.gnu reference.gnu zero.gnu
+
+      # check mass conservation
+      if awk '
+        BEGIN { min = 1000.; max = -1000.; }{ 
+          if ($5 < min) min = $5; 
+          if ($5 > max) max = $5; 
+        }
+        END {
+          if (max - min != 0.)
+            exit (1);
+        }' < t-LEVEL-ALPHA; then
+	  exit 0
+      else
+	  exit $GFS_STOP
+      fi
+  }
+}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+GfsBox {}
+1 2 right
+2 3 top
+3 4 right
+4 5 top
+5 6 right
+6 1 top
+1 3 top left
+3 5 top left
+5 1 top left
+2 6 bottom right
+4 2 bottom right
+6 4 bottom right
diff --git a/test/cosine/cosine.sh b/test/cosine/cosine.sh
new file mode 100644
index 0000000..7166c49
--- /dev/null
+++ b/test/cosine/cosine.sh
@@ -0,0 +1,60 @@
+levels="4 5 6 7"
+alphas="45 90"
+
+if ! $donotrun; then
+    for alpha in $alphas; do
+	for i in $levels; do
+	    if gerris2D -DLEVEL=$i -DALPHA=$alpha cosine.gfs 2> log-$i-$alpha; then :
+	    else
+		exit 1
+	    fi
+	done
+    done
+fi
+
+for alpha in $alphas; do
+    rm -f error-$alpha
+    for i in $levels; do
+	tail -n 1 error-$i-$alpha >> error-$alpha
+    done
+
+    if cat <<EOF | gnuplot ; then :
+set term postscript eps color enhanced lw 2 18
+set output 'order-$alpha.eps'
+set logscale
+set xtics 16,2,256
+set key spacing 1.5 bottom left
+ftitle(a,b) = sprintf("%.0f/x^{%4.2f}", exp(a), -b)
+f2(x)=a2+b2*x
+fit [3:]f2(x) 'error-$alpha' u (log(2**\$1)):(log(\$4)) via a2,b2
+fm(x)=am+bm*x
+fit [3:]fm(x) 'error-$alpha' u (log(2**\$1)):(log(\$5)) via am,bm
+set xlabel 'Spatial resolution'
+set ylabel 'Relative error norms'
+plot 'error-$alpha' u (2**\$1):4 t 'L2' w lp ps 2,  exp(f2(log(x))) t ftitle(a2,b2), \
+     'error-$alpha' u (2**\$1):5 t 'Max' w lp ps 2, exp(fm(log(x))) t ftitle(am,bm), \
+     'rossmanith$alpha' u 1:3 t 'L2 (Rossmanith)' w lp ps 2, \
+     'rossmanith$alpha' u 1:4 t 'Max (Rossmanith)' w lp ps 2 lt 1
+EOF
+    else
+	exit 1
+    fi
+done
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+c = Curve()
+print (Curve('error-45',1,4) - Curve('error-45.ref',1,4)).max()
+print (Curve('error-45',1,5) - Curve('error-45.ref',1,5)).max()
+print (Curve('error-90',1,4) - Curve('error-90.ref',1,4)).max()
+print (Curve('error-90',1,5) - Curve('error-90.ref',1,5)).max() 
+if (Curve('error-45',1,4) - Curve('error-45.ref',1,4)).max() > 1e-10 or\
+   (Curve('error-45',1,5) - Curve('error-45.ref',1,5)).max() > 1e-10 or\
+   (Curve('error-90',1,4) - Curve('error-90.ref',1,4)).max() > 1e-10 or\
+   (Curve('error-90',1,5) - Curve('error-90.ref',1,5)).max() > 1e-10:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/cosine/error-45.ref b/test/cosine/error-45.ref
new file mode 100644
index 0000000..2b246e0
--- /dev/null
+++ b/test/cosine/error-45.ref
@@ -0,0 +1,4 @@
+4 1 1.002e+00 5.316e-01 5.358e-01
+5 1 3.577e-01 2.092e-01 1.909e-01
+6 1 8.026e-02 5.107e-02 4.311e-02
+7 1 1.557e-02 1.174e-02 1.248e-02
diff --git a/test/cosine/error-90.ref b/test/cosine/error-90.ref
new file mode 100644
index 0000000..1d84b60
--- /dev/null
+++ b/test/cosine/error-90.ref
@@ -0,0 +1,4 @@
+4 1 6.565e-01 4.073e-01 3.483e-01
+5 1 2.002e-01 1.266e-01 9.351e-02
+6 1 3.949e-02 2.585e-02 1.578e-02
+7 1 8.840e-03 6.328e-03 5.954e-03
diff --git a/test/cosine/isolines.gfv b/test/cosine/isolines.gfv
new file mode 100644
index 0000000..25a2b41
--- /dev/null
+++ b/test/cosine/isolines.gfv
@@ -0,0 +1,28 @@
+# GfsView 2D
+View {
+  tx = -2.01967 ty = -2.03136
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 5.09252
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} T {
+  amin = 0 min = 0
+  amax = 0 max = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 9
+}
diff --git a/test/cosine/reference.gfv b/test/cosine/reference.gfv
new file mode 100644
index 0000000..09882fc
--- /dev/null
+++ b/test/cosine/reference.gfv
@@ -0,0 +1,28 @@
+# GfsView 2D
+View {
+  tx = -2.04454 ty = -2.04048
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 4.18068
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0.733654 b = 0.0148928
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} bell(x,y,0) {
+  amin = 0 min = 0
+  amax = 0 max = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 9
+}
diff --git a/test/cosine/rossmanith45 b/test/cosine/rossmanith45
new file mode 100644
index 0000000..a8c0e02
--- /dev/null
+++ b/test/cosine/rossmanith45
@@ -0,0 +1,6 @@
+# see Rossmanith, 2006, JCP 213, Table 3, t = 1
+# resolution L1 L2 Linfty
+20    5.02e-1 	4.01e-1		4.62e-1
+40    1.12e-1 	1.07e-1 	1.76e-1
+80    2.12e-2 	2.23e-2 	5.85e-2
+160   4.77e-3 	5.32e-3 	1.96e-2
diff --git a/test/cosine/rossmanith90 b/test/cosine/rossmanith90
new file mode 100644
index 0000000..8ab0ce7
--- /dev/null
+++ b/test/cosine/rossmanith90
@@ -0,0 +1,6 @@
+# see Rossmanith, 2006, JCP 213, Table 2, t = 1
+# resolution L1 L2 Linfty
+20    2.48e-1 1.96e-1 1.83e-1
+40    5.70e-2 4.62e-2 4.57e-2
+80    1.47e-2 1.20e-2 1.48e-2
+160   3.77e-3 3.22e-3 6.26e-3
diff --git a/test/cosine/zero.gfv b/test/cosine/zero.gfv
new file mode 100644
index 0000000..8298c7b
--- /dev/null
+++ b/test/cosine/zero.gfv
@@ -0,0 +1,28 @@
+# GfsView 2D
+View {
+  tx = -2.01967 ty = -2.03136
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 5.09252
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} T {
+  amin = 0 min = 0
+  amax = 0 max = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 0 levels = 0
+}
diff --git a/test/couette/couette.gfs b/test/couette/couette.gfs
new file mode 100644
index 0000000..dbacb26
--- /dev/null
+++ b/test/couette/couette.gfs
@@ -0,0 +1,80 @@
+# Title: Creeping Couette flow of Generalised Newtonian fluids
+#
+# Description:
+#
+# Following \cite{vola2004}, we solve for the 2D creeping flow between
+# two coaxial cylinders. The inner cylinder rotates at a constant
+# speed. The outer cylinder is fixed. The viscosity is a function of
+# the second principal invariant of the shear strain rate tensor:
+# $$|D|=\sqrt{\sum_{i,j}D_{ij}D_{ij}}$$
+# where $D_{ij}=(\partial_iu_j+\partial_ju_i)/2$.
+#
+# We use a general Herschel-Bulkley formulation of the form:
+# $$\mu(|D|)={\tau_y\over 2|D|}+\mu|D|^{N-1},$$ where $\tau_y$ is the
+# yield stress. The solutions obtained for the stationary tangential
+# velocity profiles for Newtonian, Power law ($N=0.5$),
+# Herschel-Bulkley ($\mu=0.0672$, $\tau_y=0.12$, $N=0.5$) and Bingham
+# ($\mu=1$, $\tau_y=10$, $N=1$) fluids are illustrated on Figure
+# \ref{prof}, together with the analytical solutions given by
+# \cite{bird87}.
+#
+# The Bingham fluid case is a particularly severe test of the
+# diffusion solver, as the outer part of the fluid ring ($r>0.35$)
+# behaves likes a rigid body attached to the outer boundary.
+#
+# \begin{figure}[htbp]
+# \caption{\label{prof}Tangential velocity as a function of radial position for
+# various Generalised Newtonian fluids.}
+# \begin{center}
+# \includegraphics[width=\hsize]{prof.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh couette.sh couette.gfs
+# Version: 1.0.0
+# Required files: couette.sh profile prof-0.ref prof-1.ref prof-2.ref prof-3.ref
+# Running time: 32 minutes
+# Generated files: prof.eps
+#
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+  Time { iend = 100 dtmax = 1e-2 }
+  Refine 6
+  Solid (ellipse (0,0,0.25,0.25)) { flip = 1 scale = 1.9999 }
+  Solid (ellipse (0,0,0.25,0.25))
+  ApproxProjectionParams { tolerance = 1e-6 }
+  AdvectionParams { scheme = none }
+  SourceViscosity {} {
+    double mu, ty, N, mumax = 1000.;
+    double m;
+
+    switch (MODEL) {
+    case 0: /* Newtonian */
+      mu = 1.; ty = 0.; N = 1.; break;
+    case 1: /* Power-law (shear-thinning) */
+      mu = 0.08; ty = 0.; N = 0.5; break;
+    case 2: /* Herschel-Bulkley */
+      mu = 0.0672; ty = 0.12; N = 0.5; break;
+    case 3: /* Bingham */
+      mu = 1.; ty = 10.; N = 1.; break;
+    }
+    if (D2 > 0.)
+      m = ty/(2.*D2) + mu*exp ((N - 1.)*log (D2));
+    else {
+      if (ty > 0. || N < 1.) m = mumax;
+      else m = N == 1. ? mu : 0.;
+    }
+    return MIN (m, mumax);
+  } {
+    # Crank-Nicholson does not converge for these cases, we need backward Euler
+    # (beta = 0.5 -> Crank-Nicholson, beta = 1 -> backward Euler)
+    beta = 1
+  }
+  GfsSurfaceBc U Dirichlet (x*x + y*y > 0.140625 ? 0. : - ay)
+  GfsSurfaceBc V Dirichlet (x*x + y*y > 0.140625 ? 0. :   ax)
+  EventStop { istep = 1 } U 1e-4 DU
+
+  OutputScalarNorm { istep = 1 } du-MODEL { v = DU }
+  OutputLocation { start = end } { awk '{if ($1 != "#") print $2,$8;}' > prof-MODEL } profile
+}
+GfsBox {}
diff --git a/test/couette/couette.sh b/test/couette/couette.sh
new file mode 100644
index 0000000..8e7c7b0
--- /dev/null
+++ b/test/couette/couette.sh
@@ -0,0 +1,42 @@
+if ! $donotrun; then
+    for model in 0 1 2 3; do
+	if sed "s/MODEL/$model/g" < $1 | gerris2D -; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if cat <<EOF | gnuplot ; then :
+set term postscript eps color lw 3 solid 20
+set output 'prof.eps'
+set xlabel 'r'
+set ylabel 'Tangential velocity'
+powerlaw(r,N)=r*((0.5/r)**(2./N) - 1.)/((0.5/0.25)**(2./N) - 1.)
+hb(r,Rl)=(r > Rl ? 0. : r*sqrt(2.)*0.12*0.12/(4.*0.0672*0.0672)*(3./4.+(Rl/r)**4/4.-(Rl/r)**2+log(Rl/r)))
+bingham(r,Rl)=(r > Rl ? 0. : r*sqrt(2.)*10./4.*((Rl/r)**2-2.*log(Rl/r)-1.))
+plot [0.25:0.5][0:0.25]powerlaw(x,1.) t "Newtonian", 'prof-0' w p ps 2 pt 9 t "",\
+               powerlaw(x,0.5) t "Power law", 'prof-1' w p ps 2 pt 9 t "",\
+               hb(x,0.4637) t "Herschel-Bulkley", 'prof-2' w p ps 2 pt 9 t "",\
+               bingham(x,0.34924) t "Bingham", 'prof-3' w p ps 2 pt 9 t ""
+EOF
+else
+   exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+print (Curve('prof-0',1,2) - Curve('prof-0.ref',1,2)).norm2(),\
+   (Curve('prof-1',1,2) - Curve('prof-1.ref',1,2)).norm2(),\
+   (Curve('prof-2',1,2) - Curve('prof-2.ref',1,2)).norm2(),\
+   (Curve('prof-3',1,2) - Curve('prof-3.ref',1,2)).norm2()
+if (Curve('prof-0',1,2) - Curve('prof-0.ref',1,2)).norm2() > 3.6e-4 or \
+   (Curve('prof-1',1,2) - Curve('prof-1.ref',1,2)).norm2() > 6.3e-4 or \
+   (Curve('prof-2',1,2) - Curve('prof-2.ref',1,2)).norm2() > 21e-4 or \
+   (Curve('prof-3',1,2) - Curve('prof-3.ref',1,2)).norm2() > 22e-4:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/couette/prof-0.ref b/test/couette/prof-0.ref
new file mode 100644
index 0000000..66e129b
--- /dev/null
+++ b/test/couette/prof-0.ref
@@ -0,0 +1,19 @@
+0.2625 0.228374
+0.275 0.211074
+0.2875 0.193769
+0.3 0.177503
+0.3125 0.162164
+0.325 0.147884
+0.3375 0.13429
+0.35 0.121324
+0.3625 0.108931
+0.375 0.097061
+0.3875 0.0858052
+0.4 0.0749568
+0.4125 0.0644852
+0.425 0.0543619
+0.4375 0.0445603
+0.45 0.035141
+0.4625 0.0259768
+0.475 0.017052
+0.4875 0.00940313
diff --git a/test/couette/prof-1.ref b/test/couette/prof-1.ref
new file mode 100644
index 0000000..9cfd98a
--- /dev/null
+++ b/test/couette/prof-1.ref
@@ -0,0 +1,19 @@
+0.2625 0.210866
+0.275 0.183792
+0.2875 0.158062
+0.3 0.135508
+0.3125 0.116131
+0.325 0.100148
+0.3375 0.0861675
+0.35 0.0739109
+0.3625 0.0631336
+0.375 0.0536236
+0.3875 0.0454754
+0.4 0.0381569
+0.4125 0.0315675
+0.425 0.0256176
+0.4375 0.0202283
+0.45 0.0154642
+0.4625 0.0110954
+0.475 0.00707182
+0.4875 0.0037639
diff --git a/test/couette/prof-2.ref b/test/couette/prof-2.ref
new file mode 100644
index 0000000..5bb43f0
--- /dev/null
+++ b/test/couette/prof-2.ref
@@ -0,0 +1,19 @@
+0.2625 0.184616
+0.275 0.144868
+0.2875 0.108955
+0.3 0.0796569
+0.3125 0.0569322
+0.325 0.0409685
+0.3375 0.0287308
+0.35 0.0195365
+0.3625 0.01279
+0.375 0.00798333
+0.3875 0.00500264
+0.4 0.00295887
+0.4125 0.00163182
+0.425 0.000829206
+0.4375 0.000386639
+0.45 0.000196303
+0.4625 9.1544e-05
+0.475 3.73828e-05
+0.4875 1.07438e-05
diff --git a/test/couette/prof-3.ref b/test/couette/prof-3.ref
new file mode 100644
index 0000000..327b350
--- /dev/null
+++ b/test/couette/prof-3.ref
@@ -0,0 +1,19 @@
+0.2625 0.177734
+0.275 0.129386
+0.2875 0.0852325
+0.3 0.0498059
+0.3125 0.0243925
+0.325 0.0112533
+0.3375 0.00441371
+0.35 0.00150978
+0.3625 0.000664511
+0.375 0.000487827
+0.3875 0.000428553
+0.4 0.000378624
+0.4125 0.000331367
+0.425 0.000283671
+0.4375 0.000235993
+0.45 0.000188843
+0.4625 0.000142289
+0.475 9.64123e-05
+0.4875 5.6789e-05
diff --git a/test/couette/profile b/test/couette/profile
new file mode 100644
index 0000000..9898d1d
--- /dev/null
+++ b/test/couette/profile
@@ -0,0 +1,19 @@
+0.2625 0 0
+0.275 0 0
+0.2875 0 0
+0.30 0 0
+0.3125 0 0
+0.325 0 0
+0.3375 0 0
+0.35 0 0
+0.3625 0 0
+0.375 0 0
+0.3875 0 0
+0.40 0 0
+0.4125 0 0
+0.425 0 0
+0.4375 0 0
+0.45 0 0
+0.4625 0 0
+0.475 0 0
+0.4875 0 0
diff --git a/test/depend.py b/test/depend.py
new file mode 100644
index 0000000..47876c2
--- /dev/null
+++ b/test/depend.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+sys.path.append("../doc/examples")
+import gfs2tex
+
+dists = ""
+depends = ""
+docs = ""
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            test = gfs2tex.Example(root)
+            name = test.path + "/" + test.name + ".gfs"
+            docs += "\\\n\t" + name + ".html"
+            dists += "\\\n\t" + name
+            depends += "\\\n\t" + name
+            for f in test.required:
+                dists += "\\\n\t" + test.path + "/" + f
+            for f in test.generated:
+                depends += "\\\n\t" + test.path + "/" + f
+
+print "DOCS = " + docs + dists
+print ""
+print "EXTRA_DIST += " + dists
+print ""
+print "tests.tex: " + depends
diff --git a/test/dumbell/dumbell.gfs b/test/dumbell/dumbell.gfs
new file mode 100644
index 0000000..155a9c3
--- /dev/null
+++ b/test/dumbell/dumbell.gfs
@@ -0,0 +1,20 @@
+# Title: Poisson solution in a dumbbell-shaped domain
+#
+# Description:
+#
+# Domains with a dumbbell topology can trigger an instability in the
+# Poisson solver if care is not taken.
+#
+# Author: St\'ephane Popinet
+# Command: sh dumbell.sh
+# Version: 0.9.3
+# Required files: dumbell.sh
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+  Refine 3
+  ApproxProjectionParams { nitermax = 1000 minlevel = 1 tolerance = 1e-30 }
+  Solid dumbell.gts
+  Init {} { Div = y }
+  OutputProjectionStats { istep = 1 } stdout
+}
+GfsBox {}
diff --git a/test/dumbell/dumbell.sh b/test/dumbell/dumbell.sh
new file mode 100644
index 0000000..cd18ef4
--- /dev/null
+++ b/test/dumbell/dumbell.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+bottom=.255
+top=.49
+
+tac <<EOF | shapes - > dumbell.gts
+-0.51 -0.51
+-0.51 $bottom
+-0.1 $bottom
+-0.1 $top
+0.1 $top
+0.1 $bottom
+0.51 $bottom
+0.51 -0.51
+EOF
+
+if gerris2D dumbell.gfs | awk '{
+    if ($1 == "residual.infty:" && $3 > 6.621e-02)
+      exit (1);
+  }'; then
+    :
+else
+    exit 1
+fi
diff --git a/test/geo/beta/beta.gfs b/test/geo/beta/beta.gfs
new file mode 100644
index 0000000..98e9605
--- /dev/null
+++ b/test/geo/beta/beta.gfs
@@ -0,0 +1,66 @@
+# Title: Geostrophic adjustment on a beta-plane
+#
+# Description:
+#
+# Same as before but a beta-plane, $f = f_0 + \beta y$ is used and
+# the advection terms are included in the momentum equation. No
+# explicit dissipation is added. As in {\cite{dupont}} we chose $\beta
+# = 1.607 \times 10^{- 11}$ m$^{- 1}$s$^{- 1}$.  The geostrophic eddy
+# moves slowly westward through the emission of Rossby waves and
+# southward due to the non-linear advection term. The resulting
+# evolution of the total energy is shown on figure \ref{energy}. For
+# our method, the slow decrease in the total energy is due both to the
+# dissipation of potential energy induced by the approximate
+# projection operator and to the dissipative properties of the BCG
+# upwind advection scheme. Another run with the advection terms
+# switched off (figure \ref{energy}, green curve) confirms that the
+# dissipation induced by the approximate projection operator dominates
+# the total dissipation. The results however compare favourably with
+# the finite-element formulations tested by Dupont which all show
+# significantly larger energy dissipation.
+#
+# \begin{figure}[htbp]
+# \caption{\label{energy}Evolution
+# of the total energy for the non-linear geostrophic adjustment problem. The
+# C-grid model is based on Sadourny {\cite{}} and implemented by Dupont
+# {\cite{dupont}}. The finite-element formulations are those studied by Dupont. LW:
+# Lynch and Werner {\cite{lynch87}}, LLS: Le Roux et al {\cite{leroux98}}, PZM: Peraire et al
+# {\cite{peraire86}}.}
+# \begin{center}
+# \includegraphics[width=\hsize]{energy.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh beta.sh beta.gfs
+# Version: 0.8.0
+# Required files: beta.sh c dlw lls pzm llw energy.ref energy-nonlinear.ref
+# Running time: 3 minutes
+# Generated files: energy.eps
+#
+1 0 GfsOcean GfsBox GfsGEdge {} {
+  # dt = 1000 s
+  Time { iend = 1580 dtmax = 0.10285 }
+  Refine 6
+  # Lx = Ly = 1000 km
+  # H0 = 1000 m
+  # g = 0.01 m/s^2
+  PhysicalParams { g = 9.4534734306584e-4 }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  Init {} {
+    # e-folding radius = 100 km
+    # umax = 0.5 m/s = sqrt(200)*exp(-1/2)
+    U = (5.667583815e-4*200.*y*exp (-100.*(x*x + y*y)))
+    V = (- 5.667583815e-4*200.*x*exp (-100.*(x*x + y*y)))
+    P = (5.667583815e-4*exp (-100.*(x*x + y*y)))
+    H = 1
+  }
+  # f0 = 1.0285e-4 s-1
+  # beta = 1.607e-11 m-1s-1
+  SourceCoriolis {} (1. + 0.156246961595*(y + 0.5))
+
+  OutputScalarSum { istep = 150 } { awk '{print $3/1.0285e-4/3600./24. " " $5/6.34646e-06}' > energy } { v = (Velocity2 + P*P/9.4534734306584e-4) }
+}
+GfsBox {
+  front = Boundary
+}
diff --git a/test/geo/beta/beta.sh b/test/geo/beta/beta.sh
new file mode 100644
index 0000000..661e662
--- /dev/null
+++ b/test/geo/beta/beta.sh
@@ -0,0 +1,38 @@
+if ! $donotrun; then
+    if gerris2D3 $1; then :
+    else
+	exit 1
+    fi
+    mv -f energy energy-nonlinear
+    if sed 's/Refine 6/Refine 6\nAdvectionParams {scheme = none}/' < $1 |\
+       gerris2D3 -; then :
+    else
+	exit 1
+    fi
+fi
+
+if cat <<EOF | gnuplot; then :
+    set term postscript eps lw 3 color solid 20
+    set output 'energy.eps'
+    set xlabel 'Time (days)'
+    set ylabel 'Normalised total energy'
+    set key bottom left
+    plot 'c' t 'C-grid' w lp, 'energy' t 'Gerris (linear)' w lp, 'energy-nonlinear' t 'Gerris' w lp, 'dlw' t 'Delumped LW' w lp, 'lls' t 'LLS' w lp, 'pzm' t 'PZM' w lp, 'llw' t 'Lumped LW' w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if Curve('energy',1,2).max() > 1. or \
+   Curve('energy-nonlinear',1,2).max() > 1.:
+    exit(1)
+if (Curve('energy.ref',1,2) - Curve('energy',1,2)).max() > 1e-2 or \
+   (Curve('energy-nonlinear.ref',1,2) - Curve('energy-nonlinear',1,2)).max() > 1e-2:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/geo/beta/c b/test/geo/beta/c
new file mode 100644
index 0000000..e497c33
--- /dev/null
+++ b/test/geo/beta/c
@@ -0,0 +1,12 @@
+0 1
+1.8303 0.99984162
+3.6606 0.99968176
+5.491 0.99960331
+7.3213 0.99952338
+9.1516 0.99952338
+10.9819 0.99952338
+12.8071 0.99952338
+14.6374 0.99952338
+16.4677 0.99952338
+18.298 0.99952338
+
diff --git a/test/geo/beta/dlw b/test/geo/beta/dlw
new file mode 100644
index 0000000..4841961
--- /dev/null
+++ b/test/geo/beta/dlw
@@ -0,0 +1,12 @@
+0 1
+1.73713 0.99466583
+3.47425 0.98933314
+5.2062 0.98383903
+6.94333 0.97850486
+8.68046 0.9730922
+10.4176 0.96775803
+12.1495 0.96234538
+13.8868 0.95701121
+15.6239 0.95159707
+17.361 0.94626438
+
diff --git a/test/geo/beta/energy-nonlinear.ref b/test/geo/beta/energy-nonlinear.ref
new file mode 100644
index 0000000..c115e40
--- /dev/null
+++ b/test/geo/beta/energy-nonlinear.ref
@@ -0,0 +1,11 @@
+0 1
+1.73611 0.996768
+3.47222 0.993652
+5.20833 0.990761
+6.94444 0.98795
+8.68056 0.985093
+10.4167 0.982291
+12.1528 0.97958
+13.8889 0.976855
+15.6251 0.97414
+17.3611 0.971562
diff --git a/test/geo/beta/energy.ref b/test/geo/beta/energy.ref
new file mode 100644
index 0000000..3de376a
--- /dev/null
+++ b/test/geo/beta/energy.ref
@@ -0,0 +1,11 @@
+0 1
+1.73611 0.997607
+3.47222 0.995234
+5.20833 0.992885
+6.94444 0.990559
+8.68056 0.988258
+10.4167 0.985979
+12.1528 0.983722
+13.8889 0.981484
+15.6251 0.979269
+17.3611 0.977071
diff --git a/test/geo/beta/lls b/test/geo/beta/lls
new file mode 100644
index 0000000..23cd688
--- /dev/null
+++ b/test/geo/beta/lls
@@ -0,0 +1,12 @@
+0 0.9999599
+1.73713 0.99525031
+3.47425 0.99109916
+5.2062 0.98670889
+6.94333 0.98072202
+8.68046 0.9740178
+10.4176 0.96779032
+12.1495 0.96212426
+13.8868 0.95542004
+15.6239 0.94943317
+17.361 0.94392602
+
diff --git a/test/geo/beta/llw b/test/geo/beta/llw
new file mode 100644
index 0000000..699373c
--- /dev/null
+++ b/test/geo/beta/llw
@@ -0,0 +1,12 @@
+0 1
+1.73713 0.97962145
+3.47425 0.95892304
+5.2062 0.93830607
+6.94333 0.91800601
+8.68046 0.89802582
+10.4176 0.87836403
+12.1495 0.85894214
+13.8868 0.83983716
+15.6239 0.8208936
+17.361 0.80226547
+
diff --git a/test/geo/beta/pzm b/test/geo/beta/pzm
new file mode 100644
index 0000000..e4ea0f9
--- /dev/null
+++ b/test/geo/beta/pzm
@@ -0,0 +1,12 @@
+0 1
+1.73713 0.9877397
+3.47425 0.97858483
+5.2062 0.96871469
+6.94333 0.95916146
+8.68046 0.94977113
+10.4176 0.94053629
+12.1495 0.93098602
+13.8868 0.92207106
+15.6239 0.91267776
+17.361 0.90352585
+
diff --git a/test/geo/e.ref b/test/geo/e.ref
new file mode 100644
index 0000000..0b52019
--- /dev/null
+++ b/test/geo/e.ref
@@ -0,0 +1,1581 @@
+0 5.18011e-17
+0.0115741 5.11875e-05
+0.0231481 0.000108532
+0.0347222 0.000176337
+0.0462963 0.000335961
+0.0578704 0.000540965
+0.0694444 0.000786695
+0.0810185 0.00106839
+0.0925926 0.00137833
+0.104167 0.00171154
+0.115741 0.00206062
+0.127315 0.00241816
+0.138889 0.0027757
+0.150463 0.00312689
+0.162037 0.00346434
+0.173611 0.00378062
+0.185185 0.0040694
+0.196759 0.00432434
+0.208333 0.00454225
+0.219907 0.00471678
+0.231481 0.0048469
+0.243056 0.00492835
+0.25463 0.00496114
+0.266204 0.00494421
+0.277778 0.00487969
+0.289352 0.00476862
+0.300926 0.00461312
+0.3125 0.00441742
+0.324074 0.00418576
+0.335648 0.00392343
+0.347222 0.0036357
+0.358796 0.00332788
+0.37037 0.00300842
+0.381944 0.00268155
+0.393519 0.00235469
+0.405093 0.00203312
+0.416667 0.00172423
+0.428241 0.00143228
+0.439815 0.00116359
+0.451389 0.000922095
+0.462963 0.000711273
+0.474537 0.000534618
+0.486111 0.000394352
+0.497685 0.000319248
+0.509259 0.000289841
+0.520833 0.000258
+0.532407 0.000268896
+0.543981 0.00030867
+0.555556 0.000350242
+0.56713 0.000464485
+0.578704 0.000606973
+0.590278 0.000773367
+0.601852 0.000959647
+0.613426 0.00116148
+0.625 0.0013741
+0.636574 0.00159307
+0.648148 0.00181309
+0.659722 0.002031
+0.671296 0.00224256
+0.68287 0.00244249
+0.694444 0.00262761
+0.706019 0.0027958
+0.717593 0.00294389
+0.729167 0.00306977
+0.740741 0.00317132
+0.752315 0.00324748
+0.763889 0.00329826
+0.775463 0.00332365
+0.787037 0.00332259
+0.798611 0.00329826
+0.810185 0.0032496
+0.821759 0.00317978
+0.833333 0.00309093
+0.844907 0.00298409
+0.856481 0.00286244
+0.868056 0.00272916
+0.87963 0.00258635
+0.891204 0.0024372
+0.902778 0.00228276
+0.914352 0.00212832
+0.925926 0.00197494
+0.9375 0.00182473
+0.949074 0.00168086
+0.960648 0.00154546
+0.972222 0.00141958
+0.983796 0.00130428
+0.99537 0.00120167
+1.00694 0.00111176
+1.01852 0.00103655
+1.03009 0.000975409
+1.04167 0.000928653
+1.05324 0.000896179
+1.06481 0.000877561
+1.07639 0.000872166
+1.08796 0.000879148
+1.09954 0.000897765
+1.11111 0.000926749
+1.12269 0.000964936
+1.13426 0.00101116
+1.14584 0.00106416
+1.15741 0.00112234
+1.16899 0.00118369
+1.18056 0.00124822
+1.19214 0.00131486
+1.2037 0.00138044
+1.21528 0.00144497
+1.22685 0.00150738
+1.23843 0.00156662
+1.25 0.00162163
+1.26158 0.0016724
+1.27315 0.00171789
+1.28473 0.00175597
+1.2963 0.00178876
+1.30788 0.00181521
+1.31944 0.00183425
+1.33102 0.00184694
+1.34259 0.00185223
+1.35417 0.00185117
+1.36574 0.00184271
+1.37732 0.00182896
+1.38889 0.00180992
+1.40047 0.00178453
+1.41204 0.00175491
+1.42362 0.00172
+1.43519 0.00168192
+1.44676 0.00164067
+1.45833 0.00159624
+1.46991 0.00155075
+1.48148 0.00150209
+1.49306 0.00145343
+1.50463 0.00140477
+1.51621 0.00135506
+1.52778 0.0013064
+1.53936 0.0012588
+1.55093 0.00121225
+1.56251 0.00116782
+1.57407 0.00112551
+1.58565 0.00108637
+1.59722 0.00104882
+1.6088 0.00101455
+1.62037 0.000983236
+1.63195 0.000955204
+1.64352 0.00093024
+1.6551 0.000908555
+1.66667 0.000890149
+1.67825 0.000874917
+1.68981 0.000862752
+1.70139 0.000853549
+1.71296 0.000847202
+1.72454 0.000843499
+1.73611 0.000842336
+1.74769 0.000843288
+1.75926 0.00084625
+1.77084 0.00085101
+1.78241 0.000857251
+1.79399 0.000864656
+1.80556 0.000873012
+1.81714 0.00088211
+1.8287 0.00089163
+1.84028 0.000901362
+1.85185 0.000910988
+1.86343 0.000920191
+1.875 0.000928971
+1.88658 0.00093701
+1.89815 0.000943992
+1.90973 0.000949915
+1.9213 0.00095457
+1.93288 0.000957849
+1.94444 0.000959541
+1.95602 0.000959647
+1.96759 0.000958061
+1.97917 0.000954781
+1.99074 0.00094981
+2.00232 0.00094304
+2.01389 0.000934471
+2.02547 0.000924316
+2.03704 0.000912469
+2.04862 0.000899035
+2.06019 0.000884014
+2.07176 0.000867723
+2.08333 0.000850164
+2.09491 0.000831335
+2.10648 0.000811554
+2.11806 0.00079082
+2.12963 0.000769347
+2.14121 0.000747344
+2.15278 0.000724813
+2.16436 0.000701964
+2.17593 0.00067901
+2.18751 0.000656055
+2.19907 0.000633101
+2.21065 0.000610463
+2.22222 0.000588249
+2.2338 0.000566458
+2.24537 0.000545302
+2.25695 0.000524781
+2.26852 0.000505105
+2.2801 0.000486276
+2.29167 0.000468399
+2.30325 0.000451368
+2.31481 0.0004373
+2.32639 0.000437194
+2.33796 0.00043529
+2.34954 0.00043529
+2.36111 0.000435396
+2.37269 0.000432857
+2.38426 0.000427779
+2.39584 0.000426827
+2.40741 0.000423865
+2.41899 0.000418576
+2.43056 0.000417836
+2.44214 0.000426193
+2.4537 0.000432539
+2.46528 0.000436665
+2.47685 0.000452638
+2.48843 0.000461947
+2.5 0.000465014
+2.51158 0.000469774
+2.52315 0.000476756
+2.53473 0.000478554
+2.5463 0.000476544
+2.55788 0.000471784
+2.56944 0.00046512
+2.58102 0.000460677
+2.59259 0.000455494
+2.60417 0.000448301
+2.61574 0.000440367
+2.62732 0.000432539
+2.63889 0.000423336
+2.65047 0.000411912
+2.66204 0.000402603
+2.67362 0.000392343
+2.68519 0.000379226
+2.69676 0.000370552
+2.70833 0.000399641
+2.71991 0.000448407
+2.73148 0.000489556
+2.74306 0.000522136
+2.75463 0.000545831
+2.76621 0.000559794
+2.77778 0.000563391
+2.78936 0.000558631
+2.80093 0.000548053
+2.81251 0.000535888
+2.82407 0.000522136
+2.83565 0.000508385
+2.84722 0.000506375
+2.8588 0.000502461
+2.87037 0.000496431
+2.88195 0.000489238
+2.89352 0.000483103
+2.9051 0.000475063
+2.91667 0.000464168
+2.92825 0.000456869
+2.93981 0.000446714
+2.95139 0.000435396
+2.96296 0.000425981
+2.97454 0.000462476
+2.98611 0.000517164
+2.99769 0.000562439
+3.00926 0.000597558
+3.02084 0.000622099
+3.03241 0.000635534
+3.04399 0.000637649
+3.05556 0.000630773
+3.06714 0.000619349
+3.0787 0.00060528
+3.09028 0.000591423
+3.10185 0.000576613
+3.11343 0.000561593
+3.125 0.000546254
+3.13658 0.000530281
+3.14815 0.000514097
+3.15973 0.000500134
+3.1713 0.000487969
+3.18288 0.000479401
+3.19444 0.000473794
+3.20602 0.000462264
+3.21759 0.000454013
+3.22917 0.000441637
+3.24074 0.000465437
+3.25232 0.000520338
+3.26389 0.000565401
+3.27547 0.000599991
+3.28704 0.000623686
+3.29862 0.000636486
+3.31019 0.000638178
+3.32176 0.000631197
+3.33333 0.000620407
+3.34491 0.000607819
+3.35648 0.00059449
+3.36806 0.000580527
+3.37963 0.000566458
+3.39121 0.000552284
+3.40278 0.000538109
+3.41436 0.000522771
+3.42593 0.000505846
+3.43751 0.000508596
+3.44907 0.000520549
+3.46065 0.000532714
+3.47222 0.000545091
+3.4838 0.000557784
+3.49537 0.000570584
+3.50695 0.000583595
+3.51852 0.000596818
+3.5301 0.00061004
+3.54167 0.000623263
+3.55325 0.000636591
+3.56481 0.00064992
+3.57639 0.000663248
+3.58796 0.000676471
+3.59954 0.000689588
+3.61111 0.000702705
+3.62269 0.000715504
+3.63426 0.000728304
+3.64584 0.000740786
+3.65741 0.000753162
+3.66899 0.000765221
+3.68056 0.000777175
+3.69214 0.000788811
+3.7037 0.000800235
+3.71527 0.000811448
+3.72685 0.000822449
+3.73842 0.000833239
+3.75 0.000843817
+3.76157 0.000854289
+3.77315 0.00086455
+3.78472 0.000874599
+3.7963 0.000884648
+3.80786 0.000894486
+3.81944 0.000904324
+3.83101 0.000914056
+3.84259 0.000923787
+3.85416 0.000933519
+3.86574 0.000943357
+3.87731 0.000953089
+3.88889 0.000962926
+3.90046 0.00097287
+3.91204 0.000982813
+3.92361 0.000992863
+3.93519 0.00100302
+3.94675 0.00101328
+3.95833 0.00102354
+3.9699 0.00103391
+3.98148 0.00104438
+3.99305 0.00105485
+4.00463 0.00106522
+4.0162 0.0010758
+4.02778 0.00108637
+4.03935 0.00109695
+4.05093 0.00110647
+4.06249 0.00111705
+4.07407 0.00112763
+4.08564 0.00113715
+4.09722 0.00114667
+4.10879 0.00115619
+4.12037 0.00116571
+4.13194 0.00117523
+4.14352 0.00118369
+4.15509 0.00119321
+4.16667 0.00120167
+4.17824 0.00121014
+4.18981 0.0012186
+4.20138 0.00122706
+4.21296 0.00123447
+4.22453 0.00124293
+4.23611 0.00125139
+4.24768 0.00125985
+4.25926 0.00126937
+4.27083 0.00127784
+4.28241 0.00128736
+4.29398 0.00129794
+4.30556 0.00130851
+4.31712 0.00131909
+4.3287 0.00133073
+4.34027 0.00134342
+4.35185 0.00135612
+4.36342 0.00136987
+4.375 0.00138468
+4.38657 0.00139949
+4.39815 0.00141641
+4.40972 0.00143228
+4.4213 0.00145026
+4.43286 0.00146824
+4.44444 0.00148623
+4.45601 0.00150421
+4.46759 0.00152325
+4.47916 0.00154229
+4.49074 0.00156133
+4.50231 0.00157931
+4.51389 0.0015973
+4.52546 0.00161422
+4.53704 0.00163115
+4.54861 0.00164701
+4.56019 0.00166077
+4.57175 0.00167346
+4.58333 0.00168509
+4.5949 0.00169567
+4.60648 0.00170308
+4.61805 0.00170942
+4.62963 0.00171471
+4.6412 0.00171789
+4.65278 0.00171894
+4.66435 0.00171789
+4.67593 0.00171577
+4.68749 0.0017126
+4.69907 0.00170837
+4.71064 0.00170308
+4.72222 0.00169673
+4.73379 0.00169038
+4.74537 0.00168404
+4.75694 0.00167769
+4.76852 0.0016724
+4.78009 0.00166817
+4.79167 0.001665
+4.80324 0.00166394
+4.81481 0.001665
+4.82638 0.00166817
+4.83796 0.00167452
+4.84953 0.00168298
+4.86111 0.00169567
+4.87268 0.00171154
+4.88426 0.00173058
+4.89583 0.00175279
+4.90741 0.00177818
+4.91898 0.00180674
+4.93056 0.00183848
+4.94212 0.00187339
+4.9537 0.00190935
+4.96527 0.00194849
+4.97685 0.00198763
+4.98842 0.00202888
+5 0.00207014
+5.01157 0.00211034
+5.02315 0.00215053
+5.03472 0.00218861
+5.0463 0.00222352
+5.05786 0.00225631
+5.06944 0.00228593
+5.08101 0.00231132
+5.09259 0.00233248
+5.10416 0.00234834
+5.11574 0.00235892
+5.12731 0.00236421
+5.13889 0.00236315
+5.15046 0.00235786
+5.16204 0.00234623
+5.17361 0.0023293
+5.18519 0.00230815
+5.19675 0.0022817
+5.20833 0.00225208
+5.2199 0.00221929
+5.23148 0.00218438
+5.24305 0.00214736
+5.25463 0.00211034
+5.2662 0.00207437
+5.27778 0.0020384
+5.28935 0.00200561
+5.30093 0.00197705
+5.31249 0.00195166
+5.32407 0.00193262
+5.33564 0.00191887
+5.34722 0.00191252
+5.35879 0.00191358
+5.37037 0.00192204
+5.38194 0.00193897
+5.39352 0.00196436
+5.40509 0.00199821
+5.41667 0.00204052
+5.42824 0.00208918
+5.43981 0.0021463
+5.45138 0.00220977
+5.46296 0.00227853
+5.47453 0.00235152
+5.48611 0.00242768
+5.49768 0.00250596
+5.50926 0.00258529
+5.52083 0.00266357
+5.53241 0.00273973
+5.54398 0.00281272
+5.55556 0.00288042
+5.56712 0.00294283
+5.5787 0.00299678
+5.59027 0.00304227
+5.60185 0.00307823
+5.61342 0.00310362
+5.625 0.00311843
+5.63657 0.00312266
+5.64815 0.0031142
+5.65972 0.00309516
+5.6713 0.00306554
+5.68286 0.00302534
+5.69444 0.00297563
+5.70601 0.00291745
+5.71759 0.00285186
+5.72916 0.00277993
+5.74074 0.00270483
+5.75231 0.00262655
+5.76389 0.00254721
+5.77546 0.00246893
+5.78704 0.00239383
+5.79861 0.00232296
+5.81019 0.00225843
+5.82175 0.00220237
+5.83333 0.00215582
+5.8449 0.00212091
+5.85648 0.00209658
+5.86805 0.00208601
+5.87963 0.00208918
+5.8912 0.0021061
+5.90278 0.00213678
+5.91435 0.00218121
+5.92593 0.00223939
+5.93749 0.00231026
+5.94907 0.00239171
+5.96064 0.0024848
+5.97222 0.00258529
+5.98379 0.00269319
+5.99537 0.00280638
+6.00694 0.00292274
+6.01852 0.00303909
+6.03009 0.00315545
+6.04167 0.00326758
+6.05324 0.00337548
+6.06481 0.00347491
+6.07638 0.00356589
+6.08796 0.00364628
+6.09953 0.00371398
+6.11111 0.00376793
+6.12268 0.00380707
+6.13426 0.0038314
+6.14583 0.00384092
+6.15741 0.00383351
+6.16898 0.00381236
+6.18056 0.00377533
+6.19212 0.00372456
+6.2037 0.00366109
+6.21527 0.00358704
+6.22685 0.00350347
+6.23842 0.00341144
+6.25 0.00331413
+6.26157 0.00321258
+6.27315 0.00310997
+6.28472 0.00300842
+6.2963 0.00290898
+6.30786 0.0028159
+6.31944 0.00272916
+6.33101 0.00265088
+6.34259 0.00258318
+6.35416 0.00252817
+6.36574 0.00248586
+6.37731 0.00245836
+6.38889 0.00244566
+6.40046 0.00244778
+6.41204 0.00246576
+6.42361 0.00249855
+6.43519 0.0025451
+6.44675 0.00260645
+6.45833 0.00267944
+6.4699 0.00276512
+6.48148 0.00285927
+6.49305 0.00296293
+6.50463 0.00307189
+6.5162 0.00318613
+6.52778 0.00330249
+6.53935 0.00341885
+6.55093 0.00353521
+6.56249 0.00364734
+6.57407 0.00375418
+6.58564 0.00385467
+6.59722 0.0039467
+6.60879 0.00403026
+6.62037 0.0041022
+6.63194 0.00416143
+6.64352 0.00421009
+6.65509 0.004245
+6.66667 0.00426721
+6.67824 0.00427673
+6.68981 0.00427356
+6.70138 0.00425769
+6.71296 0.00423019
+6.72453 0.00419211
+6.73611 0.00414557
+6.74768 0.0040895
+6.75926 0.00402603
+6.77083 0.00395728
+6.78241 0.00388429
+6.79398 0.00380707
+6.80556 0.00372985
+6.81712 0.00365157
+6.8287 0.00357541
+6.84027 0.00350136
+6.85185 0.00343154
+6.86342 0.00336702
+6.875 0.00330884
+6.88657 0.003257
+6.89815 0.00321363
+6.90972 0.00317873
+6.9213 0.00315228
+6.93286 0.00313536
+6.94444 0.00312901
+6.95601 0.00313112
+6.96759 0.00314382
+6.97916 0.00316497
+6.99074 0.00319565
+7.00231 0.00323585
+7.01389 0.00328345
+7.02546 0.00333846
+7.03704 0.00340087
+7.04861 0.00346857
+7.06019 0.00354261
+7.07175 0.00361983
+7.08333 0.00370129
+7.0949 0.00378485
+7.10648 0.00386948
+7.11805 0.00395516
+7.12963 0.00403978
+7.1412 0.00412335
+7.15278 0.00420375
+7.16435 0.00428097
+7.17593 0.00435396
+7.18749 0.0044206
+7.19907 0.00448195
+7.21064 0.00453696
+7.22222 0.00458456
+7.23379 0.0046237
+7.24537 0.00465437
+7.25694 0.00467553
+7.26852 0.00468928
+7.28009 0.00469246
+7.29167 0.00468717
+7.30324 0.00467236
+7.31481 0.00464908
+7.32638 0.00461735
+7.33796 0.00457821
+7.34953 0.00453167
+7.36111 0.00447878
+7.37268 0.00441954
+7.38426 0.00435713
+7.39583 0.00429049
+7.40741 0.00422173
+7.41898 0.00415086
+7.43056 0.0040821
+7.44212 0.00401334
+7.4537 0.00394776
+7.46527 0.0038864
+7.47685 0.00383034
+7.48842 0.00377956
+7.5 0.00373725
+7.51157 0.00370234
+7.52315 0.00367801
+7.53472 0.00366215
+7.5463 0.00365686
+7.55786 0.0036632
+7.56944 0.00367907
+7.58101 0.00370657
+7.59259 0.00374466
+7.60416 0.00379226
+7.61574 0.00385044
+7.62731 0.00391602
+7.63889 0.00399113
+7.65046 0.00407258
+7.66204 0.00415932
+7.67361 0.00425029
+7.68519 0.00434549
+7.69675 0.00444175
+7.70833 0.00453801
+7.7199 0.00463216
+7.73148 0.00472419
+7.74305 0.00481199
+7.75463 0.0048945
+7.7662 0.00497066
+7.77778 0.00503836
+7.78935 0.0050976
+7.80093 0.00514731
+7.81249 0.00518645
+7.82407 0.00521501
+7.83564 0.005233
+7.84722 0.0052404
+7.85879 0.00523617
+7.87037 0.00522136
+7.88194 0.00519703
+7.89352 0.00516318
+7.90509 0.00512087
+7.91667 0.00507115
+7.92824 0.00501509
+7.93981 0.00495373
+7.95138 0.00488921
+7.96296 0.00482045
+7.97453 0.00475169
+7.98611 0.00468188
+7.99768 0.00461418
+8.00926 0.00454965
+8.02083 0.0044883
+8.03241 0.00443223
+8.04398 0.00438252
+8.05556 0.0043402
+8.06712 0.0043053
+8.0787 0.00427885
+8.09027 0.00426087
+8.10185 0.00425346
+8.11342 0.00425452
+8.125 0.0042651
+8.13657 0.0042852
+8.14815 0.00431482
+8.15972 0.00435184
+8.1713 0.00439838
+8.18286 0.00445127
+8.19444 0.00451051
+8.20601 0.0045761
+8.21759 0.00464485
+8.22916 0.0047189
+8.24074 0.00479401
+8.25231 0.00487123
+8.26389 0.0049495
+8.27546 0.00502567
+8.28704 0.00510077
+8.29861 0.00517376
+8.31019 0.00524146
+8.32175 0.00530493
+8.33333 0.00536417
+8.3449 0.005416
+8.35648 0.00546148
+8.36805 0.00550062
+8.37963 0.0055313
+8.3912 0.00555563
+8.40278 0.0055715
+8.41435 0.00557996
+8.42593 0.00558102
+8.43749 0.00557467
+8.44907 0.00556092
+8.46064 0.00554188
+8.47222 0.00551755
+8.48379 0.00548687
+8.49537 0.00545302
+8.50694 0.00541494
+8.51852 0.00537369
+8.53009 0.00533137
+8.54167 0.005288
+8.55324 0.00524463
+8.56481 0.00520232
+8.57638 0.00516107
+8.58796 0.00512193
+8.59953 0.00508596
+8.61111 0.00505423
+8.62268 0.00502672
+8.63426 0.00500451
+8.64583 0.00498758
+8.65741 0.00497595
+8.66898 0.0049696
+8.68056 0.0049696
+8.69212 0.00497595
+8.7037 0.00498864
+8.71527 0.00500663
+8.72685 0.00503096
+8.73842 0.00505952
+8.75 0.00509337
+8.76157 0.00513145
+8.77315 0.00517376
+8.78472 0.00521925
+8.7963 0.00526685
+8.80786 0.00531762
+8.81944 0.0053684
+8.83101 0.00542129
+8.84259 0.00547312
+8.85416 0.0055239
+8.86574 0.00557467
+8.87731 0.00562227
+8.88889 0.00566776
+8.90046 0.00571113
+8.91204 0.00575027
+8.92361 0.00578623
+8.93519 0.00581797
+8.94675 0.00584547
+8.95833 0.00586768
+8.9699 0.00588673
+8.98148 0.00590048
+8.99305 0.00591
+9.00463 0.00591529
+9.0162 0.00591529
+9.02778 0.00591317
+9.03935 0.00590577
+9.05093 0.00589625
+9.06249 0.00588355
+9.07407 0.00586874
+9.08564 0.00585182
+9.09722 0.00583383
+9.10879 0.00581374
+9.12037 0.0057947
+9.13194 0.0057746
+9.14352 0.0057545
+9.15509 0.00573652
+9.16667 0.00571959
+9.17824 0.00570372
+9.18981 0.00568997
+9.20138 0.00567939
+9.21296 0.00567093
+9.22453 0.00566564
+9.23611 0.00566353
+9.24768 0.00566353
+9.25926 0.00566776
+9.27083 0.00567516
+9.28241 0.00568574
+9.29398 0.00569843
+9.30556 0.00571536
+9.31712 0.0057344
+9.3287 0.00575661
+9.34027 0.00577989
+9.35185 0.00580633
+9.36342 0.00583383
+9.375 0.00586345
+9.38657 0.00589413
+9.39815 0.00592481
+9.40972 0.00595654
+9.4213 0.00598828
+9.43286 0.00601895
+9.44444 0.00604963
+9.45601 0.00607925
+9.46759 0.00610781
+9.47916 0.00613531
+9.49074 0.0061607
+9.50231 0.00618397
+9.51389 0.00620618
+9.52546 0.00622523
+9.53704 0.00624321
+9.54861 0.00625802
+9.56019 0.00627071
+9.57175 0.00628235
+9.58333 0.00629081
+9.5949 0.00629716
+9.60648 0.00630245
+9.61805 0.00630562
+9.62963 0.00630773
+9.6412 0.00630773
+9.65278 0.00630668
+9.66435 0.00630562
+9.67593 0.00630245
+9.68749 0.00630033
+9.69907 0.00629716
+9.71064 0.00629398
+9.72222 0.00629081
+9.73379 0.00628764
+9.74537 0.00628552
+9.75694 0.00628446
+9.76852 0.00628446
+9.78009 0.00628552
+9.79167 0.00628658
+9.80324 0.00628975
+9.81481 0.00629398
+9.82638 0.00630033
+9.83796 0.00630668
+9.84953 0.00631514
+9.86111 0.00632466
+9.87268 0.00633524
+9.88426 0.00634793
+9.89583 0.00636063
+9.90741 0.00637543
+9.91898 0.00639024
+9.93056 0.00640611
+9.94212 0.00642304
+9.9537 0.00643996
+9.96527 0.00645794
+9.97685 0.00647593
+9.98842 0.00649391
+10 0.00651189
+10.0116 0.00652988
+10.0231 0.00654786
+10.0347 0.00656584
+10.0463 0.00658277
+10.0579 0.00659969
+10.0694 0.00661662
+10.081 0.00663248
+10.0926 0.00664835
+10.1042 0.00666316
+10.1157 0.00667691
+10.1273 0.00669066
+10.1389 0.00670336
+10.1505 0.00671605
+10.162 0.00672769
+10.1736 0.00673826
+10.1852 0.00674884
+10.1968 0.00675836
+10.2083 0.00676682
+10.2199 0.00677529
+10.2315 0.00678375
+10.243 0.00679115
+10.2546 0.0067975
+10.2662 0.00680491
+10.2778 0.0068102
+10.2893 0.00681654
+10.3009 0.00682183
+10.3125 0.00682606
+10.3241 0.00683135
+10.3356 0.00683558
+10.3472 0.00684087
+10.3588 0.0068451
+10.3704 0.00684933
+10.3819 0.00685357
+10.3935 0.00685885
+10.4051 0.00686309
+10.4167 0.00686837
+10.4282 0.00687366
+10.4398 0.00688001
+10.4514 0.00688636
+10.463 0.00689376
+10.4745 0.00690117
+10.4861 0.00690963
+10.4977 0.00691915
+10.5093 0.00692973
+10.5208 0.00694031
+10.5324 0.006953
+10.544 0.00696569
+10.5556 0.0069805
+10.5671 0.00699531
+10.5787 0.00701224
+10.5903 0.00702916
+10.6019 0.00704715
+10.6134 0.00706619
+10.625 0.00708628
+10.6366 0.00710638
+10.6481 0.00712648
+10.6597 0.00714764
+10.6713 0.00716774
+10.6829 0.00718889
+10.6944 0.00720899
+10.706 0.00722803
+10.7176 0.00724707
+10.7292 0.00726505
+10.7407 0.00728198
+10.7523 0.00729679
+10.7639 0.00731054
+10.7755 0.00732218
+10.787 0.0073317
+10.7986 0.00734016
+10.8102 0.00734545
+10.8218 0.00734968
+10.8333 0.0073518
+10.8449 0.0073518
+10.8565 0.00734968
+10.8681 0.00734651
+10.8796 0.00734227
+10.8912 0.00733593
+10.9028 0.00732958
+10.9144 0.00732218
+10.9259 0.00731371
+10.9375 0.00730631
+10.9491 0.00729996
+10.9607 0.00729362
+10.9722 0.00728833
+10.9838 0.00728515
+10.9954 0.0072841
+11.007 0.00728515
+11.0185 0.00728833
+11.0301 0.00729573
+11.0417 0.00730525
+11.0532 0.00731795
+11.0648 0.00733381
+11.0764 0.00735285
+11.088 0.00737612
+11.0995 0.00740151
+11.1111 0.00743007
+11.1227 0.00746181
+11.1343 0.0074946
+11.1458 0.00753057
+11.1574 0.00756653
+11.169 0.00760461
+11.1806 0.00764269
+11.1921 0.00767972
+11.2037 0.00771674
+11.2153 0.00775165
+11.2269 0.0077855
+11.2384 0.00781617
+11.25 0.00784368
+11.2616 0.00786801
+11.2732 0.00788811
+11.2848 0.00790397
+11.2963 0.00791561
+11.3078 0.00792301
+11.3194 0.00792513
+11.331 0.00792301
+11.3426 0.00791561
+11.3542 0.00790503
+11.3658 0.00788916
+11.3774 0.00787118
+11.3888 0.00785002
+11.4004 0.0078257
+11.412 0.00780137
+11.4236 0.00777492
+11.4352 0.00774847
+11.4468 0.00772309
+11.4584 0.00769876
+11.4699 0.00767654
+11.4815 0.0076575
+11.493 0.00764164
+11.5046 0.00763
+11.5162 0.00762365
+11.5278 0.0076226
+11.5393 0.00762683
+11.5509 0.00763635
+11.5625 0.00765221
+11.5741 0.00767443
+11.5857 0.00770087
+11.5973 0.00773367
+11.6088 0.00777069
+11.6203 0.007813
+11.6319 0.00785743
+11.6435 0.00790609
+11.6551 0.00795686
+11.6667 0.0080087
+11.6783 0.00806053
+11.6899 0.00811236
+11.7013 0.00816208
+11.7129 0.00821074
+11.7245 0.00825517
+11.7361 0.00829642
+11.7477 0.00833239
+11.7593 0.00836306
+11.7708 0.00838845
+11.7824 0.00840749
+11.794 0.00842019
+11.8056 0.00842759
+11.8171 0.00842759
+11.8287 0.0084223
+11.8403 0.00841067
+11.8518 0.0083948
+11.8634 0.00837364
+11.875 0.00834931
+11.8866 0.00832181
+11.8982 0.00829219
+11.9098 0.00826257
+11.9214 0.00823189
+11.9328 0.00820122
+11.9444 0.00817372
+11.956 0.00814833
+11.9676 0.00812611
+11.9792 0.00810919
+11.9908 0.00809649
+12.0023 0.00808909
+12.0139 0.00808697
+12.0254 0.00809121
+12.037 0.00810178
+12.0486 0.00811765
+12.0602 0.00813987
+12.0718 0.00816631
+12.0833 0.0081991
+12.0949 0.00823507
+12.1065 0.00827421
+12.1181 0.00831652
+12.1297 0.00836095
+12.1412 0.00840538
+12.1528 0.00845086
+12.1643 0.00849423
+12.1759 0.00853654
+12.1875 0.00857568
+12.1991 0.00861059
+12.2107 0.00864233
+12.2223 0.00866877
+12.2337 0.00868993
+12.2453 0.00870685
+12.2569 0.00871743
+12.2685 0.00872272
+12.2801 0.00872272
+12.2917 0.00871849
+12.3033 0.00871003
+12.3148 0.00869733
+12.3264 0.00868147
+12.338 0.00866348
+12.3495 0.00864444
+12.3611 0.0086254
+12.3727 0.00860636
+12.3843 0.00858944
+12.3958 0.00857357
+12.4074 0.00856193
+12.419 0.00855347
+12.4306 0.0085503
+12.4422 0.00855241
+12.4537 0.00855876
+12.4652 0.00857145
+12.4768 0.00858944
+12.4884 0.00861271
+12.5 0.00864021
+12.5116 0.00867406
+12.5232 0.00871108
+12.5348 0.00875128
+12.5463 0.00879359
+12.5578 0.00883802
+12.5694 0.00888245
+12.581 0.00892688
+12.5926 0.00896919
+12.6042 0.00900939
+12.6158 0.00904535
+12.6273 0.00907709
+12.6389 0.00910353
+12.6505 0.00912469
+12.662 0.00913844
+12.6736 0.00914584
+12.6852 0.00914584
+12.6967 0.0091395
+12.7083 0.0091268
+12.7199 0.00910671
+12.7315 0.00908238
+12.7431 0.0090517
+12.7547 0.00901785
+12.7663 0.00898188
+12.7777 0.00894274
+12.7893 0.00890361
+12.8009 0.00886552
+12.8125 0.00882956
+12.8241 0.00879677
+12.8357 0.00876926
+12.8473 0.00874599
+12.8588 0.00873012
+12.8703 0.00872272
+12.8819 0.00872272
+12.8935 0.00873118
+12.9051 0.00874917
+12.9167 0.00877561
+12.9282 0.00881158
+12.9398 0.008856
+12.9514 0.00890784
+12.963 0.00896707
+12.9746 0.00903266
+12.9861 0.00910353
+12.9977 0.00917652
+13.0092 0.00925268
+13.0208 0.00932885
+13.0324 0.00940501
+13.044 0.009478
+13.0556 0.00954676
+13.0672 0.00960917
+13.0788 0.00966629
+13.0902 0.00971389
+13.1018 0.00975303
+13.1134 0.00978265
+13.125 0.00980169
+13.1366 0.00980909
+13.1482 0.00980592
+13.1597 0.00979111
+13.1713 0.00976678
+13.1829 0.00973187
+13.1944 0.0096885
+13.206 0.00963773
+13.2176 0.00957955
+13.2292 0.00951608
+13.2407 0.00944944
+13.2523 0.00938174
+13.2639 0.00931298
+13.2755 0.00924528
+13.2871 0.00918181
+13.2987 0.00912363
+13.3102 0.0090718
+13.3217 0.00902737
+13.3333 0.00899246
+13.3449 0.00896813
+13.3565 0.00895544
+13.3681 0.00895332
+13.3797 0.0089639
+13.3912 0.00898612
+13.4027 0.00901997
+13.4143 0.00906651
+13.4259 0.00912257
+13.4375 0.00918816
+13.4491 0.00926326
+13.4607 0.00934471
+13.4722 0.00943145
+13.4838 0.00952348
+13.4954 0.00961657
+13.507 0.00971072
+13.5185 0.0098038
+13.5301 0.00989372
+13.5417 0.0099794
+13.5532 0.0100587
+13.5648 0.0101307
+13.5764 0.0101931
+13.588 0.010246
+13.5996 0.0102883
+13.6112 0.0103179
+13.6226 0.0103369
+13.6342 0.0103443
+13.6458 0.0103391
+13.6574 0.0103232
+13.669 0.0102957
+13.6806 0.0102587
+13.6922 0.0102121
+13.7037 0.0101582
+13.7152 0.0100979
+13.7268 0.0100323
+13.7384 0.00996248
+13.75 0.0098916
+13.7616 0.00982073
+13.7732 0.00974986
+13.7847 0.00968216
+13.7963 0.00961974
+13.8079 0.00956262
+13.8195 0.00951185
+13.831 0.00946954
+13.8426 0.00943569
+13.8541 0.00941136
+13.8657 0.00939866
+13.8773 0.00939549
+13.8889 0.00940289
+13.9005 0.00942193
+13.9121 0.00945049
+13.9237 0.00948963
+13.9351 0.00953724
+13.9467 0.00959436
+13.9583 0.00965888
+13.9699 0.00972976
+13.9815 0.00980592
+13.9931 0.00988631
+14.0047 0.00996988
+14.0162 0.0100545
+14.0278 0.0101391
+14.0393 0.0102227
+14.0509 0.0103041
+14.0625 0.0103824
+14.0741 0.0104554
+14.0856 0.0105231
+14.0972 0.0105781
+14.1088 0.0106416
+14.1204 0.0106839
+14.132 0.0107156
+14.1436 0.0107474
+14.1551 0.010758
+14.1666 0.0107685
+14.1782 0.0107685
+14.1898 0.010758
+14.2014 0.0107474
+14.213 0.0107156
+14.2246 0.0106839
+14.2362 0.0106416
+14.2476 0.0105993
+14.2592 0.0105443
+14.2708 0.0104893
+14.2824 0.0104311
+14.294 0.0103718
+14.3056 0.0103116
+14.3171 0.0102513
+14.3287 0.0101931
+14.3403 0.0101381
+14.3519 0.0100862
+14.3634 0.0100397
+14.375 0.00999738
+14.3866 0.00996248
+14.3981 0.00993497
+14.4097 0.00991487
+14.4213 0.00990324
+14.4329 0.00990006
+14.4445 0.00990641
+14.4561 0.00992122
+14.4676 0.00994449
+14.4791 0.00997729
+14.4907 0.0100185
+14.5023 0.0100672
+14.5139 0.0101233
+14.5255 0.0101867
+14.5371 0.0102565
+14.5486 0.0103306
+14.5602 0.0104089
+14.5717 0.0104903
+14.5833 0.0105728
+14.5949 0.0106522
+14.6065 0.0107368
+14.6181 0.0108214
+14.6296 0.010906
+14.6412 0.0109801
+14.6528 0.0110436
+14.6644 0.011107
+14.6759 0.0111705
+14.6875 0.0112128
+14.6991 0.0112551
+14.7106 0.0112869
+14.7222 0.011308
+14.7338 0.0113186
+14.7454 0.0113186
+14.757 0.0113186
+14.7686 0.0112974
+14.78 0.0112763
+14.7916 0.011234
+14.8032 0.0111917
+14.8148 0.0111388
+14.8264 0.0110859
+14.838 0.0110224
+14.8496 0.0109589
+14.8611 0.0108955
+14.8727 0.0108214
+14.8842 0.0107474
+14.8958 0.0106839
+14.9074 0.0106099
+14.919 0.0105527
+14.9306 0.0104946
+14.9421 0.0104438
+14.9537 0.0103994
+14.9653 0.0103634
+14.9769 0.0103369
+14.9885 0.010319
+15 0.0103126
+15.0115 0.0103158
+15.0231 0.0103295
+15.0347 0.0103539
+15.0463 0.0103888
+15.0579 0.0104332
+15.0695 0.0104882
+15.0811 0.0105506
+15.0925 0.0106204
+15.1041 0.0106945
+15.1157 0.0107791
+15.1273 0.0108637
+15.1389 0.0109589
+15.1505 0.0110541
+15.1621 0.0111493
+15.1736 0.011234
+15.1852 0.0113292
+15.1968 0.0114138
+15.2083 0.0114984
+15.2199 0.0115725
+15.2315 0.0116359
+15.243 0.0116994
+15.2546 0.0117523
+15.2662 0.0117946
+15.2778 0.0118263
+15.2894 0.0118475
+15.301 0.0118581
+15.3126 0.0118581
+15.324 0.0118475
+15.3356 0.0118263
+15.3472 0.0118052
+15.3588 0.0117629
+15.3704 0.0117206
+15.382 0.0116677
+15.3936 0.0116148
+15.4051 0.0115513
+15.4166 0.0114878
+15.4282 0.0114138
+15.4398 0.0113503
+15.4514 0.0112763
+15.463 0.0112128
+15.4745 0.0111493
+15.4861 0.0110859
+15.4977 0.011033
+15.5093 0.0109801
+15.5209 0.0109378
+15.5324 0.0108955
+15.544 0.0108743
+15.5555 0.0108532
+15.5671 0.0108426
+15.5787 0.0108426
+15.5903 0.0108532
+15.6019 0.0108743
+15.6135 0.0108955
+15.6251 0.0109378
+15.6365 0.0109801
+15.6481 0.011033
+15.6597 0.0110965
+15.6713 0.0111599
+15.6829 0.011234
+15.6945 0.011308
+15.706 0.0113821
+15.7176 0.0114667
+15.7291 0.0115513
+15.7407 0.0116254
+15.7523 0.01171
+15.7639 0.011784
+15.7755 0.0118687
+15.787 0.0119321
+15.7986 0.0119956
+15.8102 0.0120591
+15.8218 0.012112
+15.8334 0.0121648
+15.8449 0.0121966
+15.8564 0.0122283
+15.868 0.0122495
+15.8796 0.0122706
+15.8912 0.0122706
+15.9028 0.0122706
+15.9144 0.01226
+15.926 0.0122495
+15.9374 0.0122177
+15.949 0.012186
+15.9606 0.0121543
+15.9722 0.012112
+15.9838 0.0120696
+15.9954 0.0120167
+16.007 0.0119744
+16.0185 0.0119215
+16.0301 0.0118687
+16.0417 0.0118158
+16.0532 0.0117629
+16.0648 0.01171
+16.0764 0.0116677
+16.0879 0.0116254
+16.0995 0.0115936
+16.1111 0.0115619
+16.1227 0.0115302
+16.1343 0.011509
+16.1459 0.0114984
+16.1575 0.0114878
+16.1689 0.0114878
+16.1805 0.0114878
+16.1921 0.011509
+16.2037 0.0115196
+16.2153 0.0115513
+16.2269 0.011583
+16.2385 0.0116148
+16.25 0.0116571
+16.2615 0.01171
+16.2731 0.0117629
+16.2847 0.0118158
+16.2963 0.0118687
+16.3079 0.0119321
+16.3194 0.0119956
+16.331 0.0120591
+16.3426 0.0121225
+16.3542 0.012186
+16.3658 0.0122389
+16.3773 0.0123024
+16.3889 0.0123552
+16.4004 0.0124081
+16.412 0.012461
+16.4236 0.0125033
+16.4352 0.0125457
+16.4468 0.012588
+16.4584 0.0126197
+16.47 0.0126409
+16.4814 0.012662
+16.493 0.0126726
+16.5046 0.0126832
+16.5162 0.0126832
+16.5278 0.0126832
+16.5394 0.0126726
+16.5509 0.012662
+16.5625 0.0126514
+16.5741 0.0126197
+16.5856 0.0125985
+16.5972 0.0125668
+16.6088 0.0125351
+16.6204 0.0125033
+16.6319 0.012461
+16.6435 0.0124293
+16.6551 0.012387
+16.6667 0.0123552
+16.6783 0.0123129
+16.6898 0.0122812
+16.7014 0.0122389
+16.7129 0.0122072
+16.7245 0.0121754
+16.7361 0.0121543
+16.7477 0.0121331
+16.7593 0.012112
+16.7709 0.0121014
+16.7824 0.0120908
+16.7939 0.0120908
+16.8055 0.0120908
+16.8171 0.0121014
+16.8287 0.0121225
+16.8403 0.0121437
+16.8519 0.0121648
+16.8634 0.0121966
+16.875 0.0122389
+16.8866 0.0122706
+16.8981 0.0123235
+16.9097 0.0123764
+16.9213 0.0124293
+16.9329 0.0124822
+16.9444 0.0125351
+16.956 0.0125985
+16.9676 0.012662
+16.9792 0.0127255
+16.9908 0.0127784
+17.0024 0.0128418
+17.0138 0.0128947
+17.0254 0.0129582
+17.037 0.0130005
+17.0486 0.0130534
+17.0602 0.0130957
+17.0718 0.0131275
+17.0834 0.0131592
+17.0949 0.0131909
+17.1064 0.0132121
+17.118 0.0132227
+17.1296 0.0132227
+17.1412 0.0132227
+17.1528 0.0132121
+17.1644 0.0132015
+17.1759 0.0131803
+17.1875 0.0131592
+17.1991 0.0131275
+17.2107 0.0130957
+17.2222 0.0130534
+17.2338 0.0130111
+17.2453 0.0129688
+17.2569 0.0129265
+17.2685 0.0128842
+17.2801 0.0128313
+17.2917 0.012789
+17.3033 0.0127466
+17.3149 0.0127149
+17.3263 0.0126832
+17.3379 0.0126514
+17.3495 0.0126303
+17.3611 0.0126091
+17.3727 0.0125985
+17.3843 0.0125985
+17.3959 0.0125985
+17.4074 0.0126091
+17.419 0.0126197
+17.4305 0.0126514
+17.4421 0.0126832
+17.4537 0.0127149
+17.4653 0.0127678
+17.4768 0.0128101
+17.4884 0.012863
+17.5 0.0129265
+17.5116 0.0129899
+17.5232 0.0130428
+17.5348 0.0131063
+17.5463 0.0131803
+17.5578 0.0132332
+17.5694 0.0132967
+17.581 0.0133602
+17.5926 0.0134131
+17.6042 0.0134554
+17.6158 0.0134977
+17.6274 0.01354
+17.6388 0.0135717
+17.6504 0.0135929
+17.662 0.013614
+17.6736 0.0136246
+17.6852 0.0136246
+17.6968 0.0136246
+17.7083 0.013614
+17.7199 0.0135929
+17.7315 0.0135717
+17.743 0.01354
+17.7546 0.0135188
+17.7662 0.0134765
+17.7778 0.0134448
+17.7893 0.0134131
+17.8009 0.0133707
+17.8125 0.013339
+17.8241 0.0133073
+17.8357 0.0132755
+17.8473 0.0132544
+17.8588 0.0132227
+17.8703 0.0132121
+17.8819 0.0132015
+17.8935 0.0132015
+17.9051 0.0132015
+17.9167 0.0132121
+17.9283 0.0132227
+17.9398 0.0132438
+17.9513 0.0132755
+17.9629 0.0133073
+17.9745 0.0133496
+17.9861 0.0133919
+17.9977 0.0134342
+18.0093 0.0134871
+18.0208 0.0135294
+18.0324 0.0135823
+18.044 0.0136352
+18.0556 0.0136775
+18.0671 0.0137198
+18.0787 0.0137621
+18.0903 0.0137939
+18.1018 0.0138256
+18.1134 0.0138468
+18.125 0.0138679
+18.1366 0.0138785
+18.1482 0.0138891
+18.1598 0.0138785
+18.1712 0.0138679
+18.1828 0.0138573
+18.1944 0.0138362
+18.206 0.013815
+18.2176 0.0137833
+18.2292 0.0137516
+18.2408 0.0137198
+18.2523 0.0136881
+18.2639 0.0136458
+18.2754 0.013614
+18.287 0.0135823
diff --git a/test/geo/geo.gfs b/test/geo/geo.gfs
new file mode 100644
index 0000000..9d2735c
--- /dev/null
+++ b/test/geo/geo.gfs
@@ -0,0 +1,117 @@
+# Title: Geostrophic adjustment
+#
+# Description:
+#
+# We consider the geostrophic adjustment problem studied by
+# Dupont {\cite{dupont}} and Le Roux et al {\cite{leroux98}}. A Gaussian bump
+# \[ \eta ( x, y ) = \eta_0 e^{^{- \frac{x^2 + y^2}{R^2}}} \]
+# is initialised in a 1000$\times$1000 km, 1000 m deep square basin. A reduced
+# gravity $g = 0.01$ m/s$^2$ is used to approximate a 10 m-thick stratified surface
+# layer. On an $f$-plane the corresponding geostrophic velocities are given by
+# \begin{eqnarray*}
+#   u ( x, y ) & = & \frac{2 g \eta_0 y}{f_0 R^2} e^{- \frac{x^2 + y^2}{R^2}},\\
+#   v ( x, y ) & = & - \frac{2 g \eta_0 x}{f_0 R^2} e^{- \frac{x^2 + y^2}{R^2}},
+# \end{eqnarray*}
+# where $f_0$ is the Coriolis parameter. Following Dupont we set $f_0 = 1.0285
+# \times 10^{- 4}$ s$^{- 1}$, $R = 100$ km, $\eta_0 = 599.5$ m which gives a
+# maximum geostrophic velocity of 0.5 m/s.
+#
+# In the context of the linearised shallow-water equations, the geostrophic
+# balance is an exact solution which should be preserved by the numerical
+# method. In practice, this would require an exact numerical balance between
+# terms computed very differently: the pressure gradient and the Coriolis terms
+# in the momentum equation. If this numerical balance is not exact, the
+# numerical solution will adjust toward numerical equilibrium through the
+# emission of gravity-wave noise which should not affect the stability of the
+# solution. This problem is thus a good test of both the overall accuracy of the
+# numerical scheme and its stability properties when dealing with
+# inertia--gravity waves. We note in particular that a standard A-grid
+# discretisation would develop a strong computational-mode instability in this
+# case. Also, as studied by Leroux et al, an inappropriate choice of
+# finite-element basis functions will result in growing gravity-wave noise.
+#
+# \begin{figure}[htbp]
+# \caption{\label{geo-error}Evolution of the maximum error on the surface height for the 
+# geostrophic adjustment problem.}
+# \begin{center}
+# \includegraphics[width=\hsize]{geo_error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{geo-error1}Evolution of the surface-height error field. (a) $t =$1.157
+# days, (b) $t = 2.315$ days, (c) $t =$3.472 days, (d) $t =$4.630 days, (e) $t
+# =$17.361 days.}
+# \begin{center}
+# \begin{tabular}{ccccc}
+# \includegraphics[width=0.18\hsize]{error-100.eps} &
+# \includegraphics[width=0.18\hsize]{error-200.eps} &
+# \includegraphics[width=0.18\hsize]{error-300.eps} &
+# \includegraphics[width=0.18\hsize]{error-400.eps} &
+# \includegraphics[width=0.18\hsize]{error-1500.eps} \\
+#   (a) & (b) & (c) & (d) & (e)
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Figures \ref{geo-error} and \ref{geo-error1} summarise the results obtained
+# when running the geostrophic adjustment problem on a $64 \times 64$ uniform
+# grid with a timestep $\Delta t = 1000$ s. The maximum error on the height
+# field (Figure \ref{geo-error}) is small even after 18 days. After a strong
+# initial transient corresponding to the emission of gravity waves, the error
+# reaches a minimum at day 3 and then slowly grows with time with modulations
+# due to the reflexions of the initial gravity waves on the domain boundaries.
+# As illustrated on figure \ref{geo-error1}, this growth is not due to any
+# instability of the solution but to the slow decrease of the maximum amplitude
+# of the Gaussian bump due to numerical energy dissipation.
+#
+# Author: St\'ephane Popinet
+# Command: sh geo.sh geo.gfs
+# Version: 0.8.0
+# Required files: geo.sh geo.gfv e.ref
+# Running time: 3 minutes
+# Generated files: geo_error.eps error-100.eps error-200.eps error-300.eps error-400.eps error-1500.eps
+#
+1 0 GfsOcean GfsBox GfsGEdge {} {
+  # dt = 1000 s
+  Time { iend = 1580 dtmax = 0.10285 }
+  Refine 6
+  # Lx = Ly = 1000 km
+  # H0 = 1000 m
+  # g = 0.01 m/s^2
+  PhysicalParams { g = 9.4534734306584e-4 }
+  AdvectionParams { scheme = none }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  Init {} {
+    # e-folding radius = 100 km
+    # umax = 0.5 m/s = sqrt(200)*exp(-1/2)
+    U = (5.667583815e-4*200.*y*exp (-100.*(x*x + y*y)))
+    V = (- 5.667583815e-4*200.*x*exp (-100.*(x*x + y*y)))
+    P = (5.667583815e-4*exp (-100.*(x*x + y*y)))
+    H = 1
+  }
+  # f0 = 1.0285e-4 s-1
+  SourceCoriolis {} 1
+
+  OutputErrorNorm { istep = 1 } { awk '{print $3/1.0285e-4/3600./24. " " $9*1000e6*1.0285e-4*1.0285e-4/0.01;}' > e } { v = P } {
+    s = (5.667583815e-4*exp (-100.*(x*x + y*y)))
+    unbiased = 1
+    v = E
+  }
+  OutputSimulation { istart = 100 iend = 500 istep = 100 } stdout
+  EventScript { istart = 100 iend = 500 istep = 100 } { echo "Save error-$GfsIter.eps { format = EPS }"}
+  OutputSimulation { istart = 1500 } stdout
+  EventScript { istart = 1500 } { echo "Save error-$GfsIter.eps { format = EPS }"}
+  EventScript { start = end } {
+    cat <<EOF | gnuplot
+    set term postscript eps lw 3 color solid 20
+    set output 'geo_error.eps'
+    set xlabel 'Time (days)'
+    set ylabel 'Maximum error on surface height (cm)'
+    plot 'e.ref' u 1:(\$2*100.) t '' w l, 'e' u 1:(\$2*100.) t 'ref' w l
+EOF
+  }
+}
+GfsBox {
+  front = Boundary
+}
diff --git a/test/geo/geo.gfv b/test/geo/geo.gfv
new file mode 100644
index 0000000..d61f0af
--- /dev/null
+++ b/test/geo/geo.gfv
@@ -0,0 +1,22 @@
+# GfsView 3D
+View {
+  tx = 0 ty = 0
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = -0.5
+} E {
+  amin = 1
+  amax = 1
+  cmap = Jet
+}
diff --git a/test/geo/geo.sh b/test/geo/geo.sh
new file mode 100644
index 0000000..7596ee8
--- /dev/null
+++ b/test/geo/geo.sh
@@ -0,0 +1,16 @@
+if ! $donotrun; then
+    if gerris2D3 $1 | gfsview-batch2D3 geo.gfv; then :
+    else
+	exit 1
+    fi
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('e',1,2) - Curve('e.ref',1,2)).max() > 1e-3:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/gfs2tex b/test/gfs2tex
new file mode 100644
index 0000000..0cb556c
--- /dev/null
+++ b/test/gfs2tex
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+import glob
+sys.path.append("../doc/examples")
+import gfs2tex
+
+if not os.access("tests",os.F_OK):
+    os.mkdir("tests")
+
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            example = gfs2tex.Example(root)
+            if not os.access("tests/" + example.path,os.F_OK):
+                os.symlink("../" + example.path, "tests/" + example.path)
+            example.write(style="tests.css")
diff --git a/test/hexagon/hexagon.gfs b/test/hexagon/hexagon.gfs
new file mode 100644
index 0000000..e8dab9f
--- /dev/null
+++ b/test/hexagon/hexagon.gfs
@@ -0,0 +1,74 @@
+# Title: Translation of an hexagon in a uniform flow
+#
+# Description: 
+#
+# An hexagonal solid object translates uniformly in a fluid moving at
+# the same speed (U = 1). There is no diffusion.
+#
+# The conservation properties of the scheme can be checked by filling
+# the simulation domain with tracer and computing the total amount at
+# each time step.
+# 
+# \begin{figure}[htbp]
+# \caption{\label{errorvelocitytime} Error in the horizontal component
+# of the velocity field. Dark blue is zero, dark red 0.1.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{end-2.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{ordertime} Evolution of the global RMS error on the
+# velocity field.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: S\'ebastien Delaux
+# Command: sh hexagon.sh hexagon.gfs
+# Version: 090502
+# Required files: hexagon.sh hexagon.gts hexagon.gfv
+# Generated files: error.eps end-2.eps
+#
+2 1 GfsSimulationMoving GfsBox GfsGEdge {} {
+  Time { end = .1875 }
+  Refine 7
+
+  SolidMoving hexagon.gts { scale = 0.250001 } { level = 7 }
+  AdvectionParams { 
+      moving_order = ORDER 
+      # uncommenting the following line leads to instabilities for the
+      # first-order scheme 
+      # cfl = 0.45
+  }
+  
+  ProjectionParams { tolerance = 1e-10 }
+  ApproxProjectionParams { tolerance = 1e-10 }
+
+  AdaptVorticity { istep = 1 } { minlevel = 4 maxlevel = 7 cmax = 1e-2 }
+
+  VariableTracer T
+ 
+  SurfaceBc U Dirichlet 1.
+
+  Init {} { U = 1 T = 1 }
+
+  OutputErrorNorm { istep = 1 } {
+      awk '{ printf ("%e %e %e %e\n", $3, $5, $7, $9) }' > momentumerror-ORDER
+  } { v = sqrt((U - 1.)*(U - 1.) + V*V) } { s = 0. }
+
+  OutputScalarSum { istep = 1 } {
+      awk '{ printf ("%e %e\n", $3, $5 - 1.953125) }' > tracersum-ORDER
+  } { v = T }
+  OutputSimulation { start = end } end-ORDER.gfs
+  
+}
+GfsBox {
+    left = Boundary {
+	BcDirichlet U 1
+	BcDirichlet T 1
+    }
+}
+GfsBox { right = BoundaryOutflow }
+1 2 right
diff --git a/test/hexagon/hexagon.gfv b/test/hexagon/hexagon.gfv
new file mode 100644
index 0000000..a20b764
--- /dev/null
+++ b/test/hexagon/hexagon.gfv
@@ -0,0 +1,23 @@
+# GfsView 2D
+View {
+  tx = -0.180022 ty = -0.0101632
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 6.36061
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} fabs(U-1) {
+  amin = 0 min = 1.64428e-08
+  amax = 0 max = 0.1
+  cmap = Jet
+}
diff --git a/test/hexagon/hexagon.gts b/test/hexagon/hexagon.gts
new file mode 100644
index 0000000..b4fdd9b
--- /dev/null
+++ b/test/hexagon/hexagon.gts
@@ -0,0 +1,387 @@
+66 192 128 GtsSurface GtsFace GtsEdge GtsVertex
+0.25 -0.5 0.6
+0.25 -0.5 0.8
+-0.25 -0.5 0.8
+-0.5 0 0.6
+-0.25 -0.5 0.6
+-0.5 0 0.8
+-0.25 0.5 -1
+-0.25 0.5 -0.8
+0.25 0.5 -0.8
+-0.25 0.5 0.8
+-0.25 0.5 1
+0.5 0 -0.8
+0.5 0 -0.6
+0.5 0 -0.4
+0.25 0.5 -0.4
+0.5 0 -0.2
+-0.5 0 -1
+0.5 0 -1
+0.25 0.5 -1
+0.25 0.5 0.4
+0.25 0.5 0.6
+0.5 0 0.6
+-0.5 0 -0.6
+-0.5 0 -0.4
+-0.25 0.5 -0.4
+-0.25 0.5 0.6
+0.25 0.5 0.8
+0.5 0 0.2
+0.5 0 0.4
+0.25 -0.5 0.4
+-0.25 -0.5 0.2
+0.25 -0.5 0.2
+-0.25 -0.5 0.4
+0.25 0.5 -5.551115123e-17
+-0.25 0.5 -5.551115123e-17
+0.25 0.5 0.2
+0.25 -0.5 -1
+0.25 -0.5 -0.8
+-0.25 -0.5 -0.8
+0.25 -0.5 -0.2
+0.25 0.5 -0.6
+0.25 0.5 -0.2
+0.5 0 -5.551115123e-17
+0.25 -0.5 1
+-0.25 -0.5 1
+-0.25 -0.5 -0.4
+0.25 -0.5 -0.4
+-0.25 -0.5 -0.2
+0.25 -0.5 -5.551115123e-17
+-0.25 -0.5 -5.551115123e-17
+-0.5 0 1
+-0.25 -0.5 -1
+0.25 -0.5 -0.6
+-0.25 0.5 0.2
+-0.25 0.5 -0.2
+-0.5 0 0.2
+-0.5 0 0.4
+0.25 0.5 1
+-0.5 0 -0.8
+-0.5 0 -0.2
+-0.5 0 -5.551115123e-17
+0.5 0 1
+-0.25 0.5 0.4
+-0.25 -0.5 -0.6
+0.5 0 0.8
+-0.25 0.5 -0.6
+1 2
+1 3
+3 2
+4 5
+4 6
+5 6
+7 8
+7 9
+9 8
+10 6
+10 11
+6 11
+12 9
+12 13
+9 13
+14 15
+14 16
+15 16
+17 18
+18 19
+17 19
+20 21
+20 22
+22 21
+4 10
+23 24
+23 25
+25 24
+18 12
+19 12
+21 26
+21 27
+26 27
+28 29
+28 30
+30 29
+31 32
+31 33
+32 33
+34 35
+34 36
+35 36
+37 38
+37 39
+39 38
+33 30
+33 5
+30 5
+14 40
+40 16
+13 41
+13 14
+41 14
+42 34
+42 43
+43 34
+2 44
+2 45
+45 44
+46 47
+46 48
+47 48
+43 28
+43 32
+32 28
+7 17
+19 7
+40 49
+16 49
+50 49
+50 31
+49 31
+5 3
+6 3
+6 51
+11 51
+9 41
+15 42
+16 42
+17 52
+52 18
+53 13
+53 47
+13 47
+38 12
+38 53
+12 53
+19 9
+41 15
+36 54
+36 20
+54 20
+26 10
+27 10
+37 18
+18 38
+25 55
+24 55
+32 30
+30 1
+5 1
+56 31
+56 57
+31 57
+3 45
+3 51
+51 45
+57 33
+57 4
+33 4
+47 40
+48 40
+27 58
+10 58
+16 43
+49 43
+17 59
+52 59
+24 46
+24 60
+46 60
+49 32
+48 50
+40 50
+61 50
+61 56
+50 56
+51 62
+45 62
+54 56
+54 63
+56 63
+20 63
+63 21
+64 53
+64 46
+53 46
+62 58
+51 58
+39 64
+38 64
+60 48
+60 61
+48 61
+22 65
+21 65
+55 60
+59 39
+59 23
+39 23
+65 27
+65 62
+27 62
+34 28
+42 55
+55 34
+58 11
+52 39
+47 14
+63 57
+63 26
+57 26
+1 22
+22 2
+8 41
+35 61
+35 54
+61 54
+23 64
+64 24
+55 35
+60 35
+41 66
+66 15
+28 36
+36 29
+29 1
+8 59
+8 66
+59 66
+17 8
+15 25
+25 42
+2 65
+65 44
+26 4
+52 37
+29 20
+29 22
+66 23
+66 25
+44 62
+1 2 3
+4 5 6
+7 8 9
+10 11 12
+13 14 15
+16 17 18
+19 20 21
+22 23 24
+5 25 10
+26 27 28
+20 29 30
+31 32 33
+34 35 36
+37 38 39
+40 41 42
+43 44 45
+46 47 48
+17 49 50
+51 52 53
+54 55 56
+57 58 59
+60 61 62
+63 64 65
+66 21 67
+50 68 69
+70 71 72
+73 6 74
+75 12 76
+77 15 51
+78 18 79
+19 80 81
+82 83 84
+85 86 87
+88 30 13
+89 53 16
+90 91 92
+93 33 94
+95 43 96
+28 97 98
+99 39 46
+100 48 101
+102 103 104
+105 106 107
+108 109 110
+111 62 112
+94 113 114
+115 69 116
+80 117 118
+119 120 121
+122 72 37
+112 123 124
+125 126 127
+107 128 129
+130 131 132
+14 87 82
+133 22 134
+135 136 137
+138 128 139
+45 140 141
+142 143 144
+131 92 133
+29 96 85
+24 145 146
+120 98 147
+148 149 150
+151 152 153
+38 104 108
+56 63 154
+155 54 156
+47 110 4
+11 114 157
+158 118 148
+52 84 159
+160 161 162
+163 1 164
+61 121 142
+68 124 70
+71 127 102
+139 76 157
+9 77 165
+166 167 168
+161 134 31
+83 137 60
+86 141 135
+169 26 170
+123 144 125
+67 88 8
+147 171 172
+173 89 174
+167 42 90
+175 34 176
+32 146 151
+36 100 177
+113 153 138
+178 179 180
+41 154 175
+171 156 40
+66 7 181
+182 78 183
+103 132 160
+184 57 185
+109 162 186
+145 164 184
+101 73 2
+179 165 173
+126 168 130
+81 187 95
+188 189 23
+136 170 119
+140 150 169
+186 93 25
+190 191 27
+143 172 166
+191 174 182
+91 176 188
+189 177 163
+65 99 35
+149 180 190
+187 158 44
+74 75 106
+3 105 58
+117 181 178
+97 183 155
+152 185 192
+159 111 49
+79 115 55
+116 122 64
+59 129 192
diff --git a/test/hexagon/hexagon.sh b/test/hexagon/hexagon.sh
new file mode 100644
index 0000000..c0dacf4
--- /dev/null
+++ b/test/hexagon/hexagon.sh
@@ -0,0 +1,41 @@
+if ! $donotrun; then
+    for order in 1 2 ; do
+	if gerris2D -DORDER=$order hexagon.gfs; then :
+	else
+	    exit 1
+	fi
+    done
+
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'error.eps'
+    set xlabel 'Time'
+    set ylabel 'Norm2 of error on the velocity field'
+    set yr [1e-10:0.1]
+    set log y
+    plot 'momentumerror-1' t 'first order' w lp, \
+         'momentumerror-2' t 'second order' w lp
+EOF
+else
+    exit 1
+fi
+
+if echo "Save end-2.eps { format = EPS }" | gfsview-batch2D end-2.gfs hexagon.gfv; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if Curve('tracersum-1',1,2).normi() > 1e-6 or \
+   Curve('tracersum-2',1,2).normi() > 5e-6 or \
+   Curve('momentumerror-1',1,3).max() > 11e-3 or \
+   Curve('momentumerror-2',1,3).max() > 2e-3:
+    exit(1)
+EOF
+else
+    exit 1
+fi
diff --git a/test/hydrostatic/hydrostatic.gfs b/test/hydrostatic/hydrostatic.gfs
new file mode 100644
index 0000000..601379c
--- /dev/null
+++ b/test/hydrostatic/hydrostatic.gfs
@@ -0,0 +1,30 @@
+# Title: Hydrostatic balance with solid boundaries and viscosity
+#
+# Description:
+#
+# Checks that hydrostatic balance is accurately computed when coupled
+# with the Crank-Nicholson discretisation of viscous terms.
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D hydrostatic.gfs
+# Version: 1.1.3
+# Required files: hydrostatic.gfs
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Refine 3
+    Source V -1
+    SourceViscosity 1e-2
+    Solid (ellipse(0.,0.,0.24,0.24))
+    Time { iend = 10 }
+    ApproxProjectionParams { tolerance = 1e-12 }
+    ProjectionParams { tolerance = 1e-12 }
+
+    OutputScalarNorm { istep = 1 } v { v = V }
+    EventScript { start = end } { 
+        if awk '{if ($9 > 1e-12) exit (1);}' < v ; then
+            exit 0;
+        else
+            exit $GFS_STOP;
+        fi
+    } 
+}
+GfsBox {}
diff --git a/test/hydrostatic/quadratic/quadratic.gfs b/test/hydrostatic/quadratic/quadratic.gfs
new file mode 100644
index 0000000..cce31c5
--- /dev/null
+++ b/test/hydrostatic/quadratic/quadratic.gfs
@@ -0,0 +1,46 @@
+# Title: Hydrostatic balance with quadratic pressure profile
+#
+# Description:
+#
+# Same test as before but for a quadratic pressure profile.
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D quadratic.gfs
+# Version: 1.2.0
+# Required files: quadratic.gfs
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Refine 3
+
+    # This test case only works for constant refinement
+    #    Refine (x*x + y*y < 0.2*0.2 ? 4 : 3) 
+
+    # Note: it is important to use 'cy' rather than 'y' in the formula
+    # below so that the hydrostatic density distribution is correct
+    # even for 'cut cells'
+    Init {} { rho = (cy + 0.5) }
+
+    Source V -rho
+    SourceViscosity 1e-2
+    Solid (ellipse(0.,0.,0.24,0.24))
+    Time { iend = 10 }
+    ApproxProjectionParams { tolerance = 1e-12 }
+    ProjectionParams { tolerance = 1e-12 }
+
+    OutputScalarNorm { istep = 1 } v { v = V }
+    # Checks that the pressure profile is close to the exact solution
+    OutputErrorNorm { istep = 1 } p { v = P } {
+        s = -(cy*cy/2. + 0.5*cy) 
+        unbiased = 1 
+    }
+    EventScript { start = end } { 
+        if awk '{if ($9 > 1e-12) exit (1);}' < v ; then :
+        else
+            exit $GFS_STOP;
+        fi        
+        if awk '{if ($9 > 1e-12) exit (1);}' < p ; then :
+        else
+            exit $GFS_STOP;
+        fi
+    } 
+}
+GfsBox {}
diff --git a/test/kinetic/kinetic.gfs b/test/kinetic/kinetic.gfs
new file mode 100644
index 0000000..3badab7
--- /dev/null
+++ b/test/kinetic/kinetic.gfs
@@ -0,0 +1,69 @@
+# Title: Momentum conservation for large density ratios
+#
+# Description:
+#
+# A dense droplet moves through a lighter background fluid. The
+# kinetic energy decreases due to viscous dissipation (Figure
+# \ref{k}). For these density and viscosity ratios of 1000, the
+# calculation is stable only if a "mollified" volume fraction is used
+# to compute the average density and viscosity.
+#
+# \begin{figure}[htbp]
+# \caption{\label{k}Evolution of the kinetic energy.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{k.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D kinetic.gfs
+# Version: 1.1.0
+# Required files: kinetic.gfs
+# Generated files: k.eps
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Time { end = 0.5 }
+
+    Global {
+        #define var(T,min,max) (CLAMP(T,0,1)*(max - min) + min)
+        #define rho(T) var(T, 0.001, 1.)
+        #define mu(T)  var(T, 1e-6, 1e-3)
+        #define level 7
+        #define radius 0.05
+    }
+
+    Refine level
+
+    ProjectionParams { tolerance = 1e-6 }
+    ApproxProjectionParams { tolerance = 1e-6 }
+
+    VariableTracerVOF T
+    VariableFiltered T1 T 1
+    InitFraction T (- ellipse(-0.3,0,radius,radius))
+    Init {} { U = T }
+
+    PhysicalParams { alpha = 1./rho(T1) }
+    SourceViscosity mu(T1)
+
+    AdaptVorticity { istep = 1 } { cmax = 0.3 maxlevel = level }
+    AdaptGradient { istep = 1 } { cmax = 1e-3 maxlevel = level } T
+
+    OutputScalarSum { istep = 1 } k { v = Velocity2*rho(T1) }
+    OutputScalarSum { istep = 1 } t { v = T }
+
+    EventScript { start = end } {
+        gnuplot <<EOF
+            set term postscript eps color lw 3 solid 20
+            set output 'k.eps'
+            set xlabel 'Time'
+            set ylabel 'Kinetic energy'
+            set grid
+            plot 'k' u 3:5 w l t ''
+EOF
+        if awk '{if ($5 > 7.2e-3) exit (1);}' < k ; then
+            return 0;
+        else
+            return $GFS_STOP;
+        fi
+    } 
+}
+GfsBox {}
diff --git a/test/lid/explicit/explicit.gfs b/test/lid/explicit/explicit.gfs
new file mode 100644
index 0000000..9432001
--- /dev/null
+++ b/test/lid/explicit/explicit.gfs
@@ -0,0 +1,88 @@
+# Title: Lid-driven cavity at Re=1000 (explicit scheme)
+#
+# Description:
+#
+# Same test case but with an explicit scheme for the viscous term.
+#
+# Author: St\'ephane Popinet
+# Command: sh lid.sh explicit.gfs
+# Version: 1.3.0
+# Required files: lid.sh
+# Running time: 70 minutes
+# Generated files: xprof yprof xprof.eps yprof.eps velocity.eps
+#
+# The simulation domain has 1 GfsBox
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+
+  # Stop the simulation at t = 300 if convergence has not been reached before
+  Time { end = 300 }
+
+  # Use an initial refinement of 6 levels (i.e. 2^6=64x64)
+  Refine 6
+
+  # Set a viscosity source term on the velocity vector with x-component U
+  # The Reynolds number is Re = L*U/Nu = 1*1/1e-3 = 1000
+  SourceViscosityExplicit 1e-3
+
+  # Stops the simulation if the maximum of the absolute value of the
+  # difference between the current U field and the U field 10 timesteps
+  # before is smaller than 1e-4.
+  #
+  # Stores this difference in the DU field (this can be used for
+  # monitoring the convergence of the simulation).
+  EventStop { istep = 10 } U 1e-4 DU
+
+  OutputScalarNorm { istep = 10 } du { v = DU }
+
+  # Pipes a bitmap PPM image representation of the velocity field at the end of the simulation
+  # into the ImageMagick converter "convert" to create the
+  # corresponding EPS file
+  OutputPPM { start = end } { convert -colors 256 ppm:- velocity.eps } {
+    v = Velocity
+  }
+
+  # At the end of the simulation, computes the values of the variables
+  # at the locations defined in files xprofile, yprofile and stores the
+  # results in files xprof, yprof
+  OutputLocation { start = end } xprof ../xprofile
+  OutputLocation { start = end } yprof ../yprofile
+
+  # At the end of the simulation calls the script generating the EPS
+  # files using gnuplot and files: xprof, yprof, xprof.ghia, yprof.ghia
+  EventScript { start = end } {
+    cat <<EOF | gnuplot
+    set term postscript eps lw 3 solid 20
+    set output 'xprof.eps'
+    set xlabel 'Y'
+    set ylabel 'U'
+    plot [-0.5:0.5]'../xprof.ghia' u 1:2 title "Ghia et al." w p ps 2 pt 9, 'xprof' u 3:7 w l title "Gerris"
+    set output 'yprof.eps'
+    set xlabel 'X'
+    set ylabel 'V'
+    plot [-0.5:0.5]'../yprof.ghia' u 1:2 title "Ghia et al." w p ps 2 pt 9, 'yprof' u 2:8 w l title "Gerris"
+EOF
+  }
+}
+GfsBox {
+
+  # Dirichlet boundary conditions for both components of the velocity on all sides:
+  # - non-slip (U = V = 0) on right, left and bottom boundaries
+  # - tangential velocity equal to 1 (U = 1) on top boundary
+
+  top = Boundary {
+    BcDirichlet U 1
+    BcDirichlet V 0
+  }
+  bottom = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+  right = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+  left = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+}
diff --git a/test/lid/explicit/lid.sh b/test/lid/explicit/lid.sh
new file mode 100644
index 0000000..12c44a9
--- /dev/null
+++ b/test/lid/explicit/lid.sh
@@ -0,0 +1,19 @@
+if ! $donotrun; then
+    if gerris2D $1; then :
+    else
+	exit 1
+    fi
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+print (Curve('xprof',3,7) - Curve('../xprof.ghia',1,2)).normi()
+print (Curve('yprof',2,8) - Curve('../yprof.ghia',1,2)).normi()
+if (Curve('xprof',3,7) - Curve('../xprof.ghia',1,2)).normi() > 2.2e-2 or \
+   (Curve('yprof',2,8) - Curve('../yprof.ghia',1,2)).normi() > 2.1e-2:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/lid/lid.gfs b/test/lid/lid.gfs
new file mode 100644
index 0000000..680df43
--- /dev/null
+++ b/test/lid/lid.gfs
@@ -0,0 +1,121 @@
+# Title: Lid-driven cavity at Re=1000
+#
+# Description:
+#
+# The classical lid-driven cavity test case.
+#
+# This example illustrates how to check for the convergence toward a
+# stationary solution of an initially time-dependent problem.
+#
+# The stationary solution obtained is illustrated on Figure \ref{velocity}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{velocity}Norm of the velocity for the stationary regime.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{velocity.eps}
+# \end{center}
+# \end{figure}
+#
+# Velocity profiles are generated automatically and compared to the
+# benchmark results of Ghia et al. \cite{ghia82} on
+# Figures \ref{xprof} and \ref{yprof}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{xprof}Vertical profile of the $x$-component of the velocity on
+# the centerline of the box.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{xprof.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{yprof}Horizontal profile of the $y$-component of the velocity on
+# the centerline of the box.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{yprof.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh lid.sh lid.gfs
+# Version: 0.6.4
+# Required files: lid.sh xprofile yprofile xprof.ghia yprof.ghia
+# Running time: 70 minutes
+# Generated files: xprof yprof xprof.eps yprof.eps velocity.eps
+#
+# The simulation domain has 1 GfsBox
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+
+  # Stop the simulation at t = 300 if convergence has not been reached before
+  Time { end = 300 }
+
+  # Use an initial refinement of 6 levels (i.e. 2^6=64x64)
+  Refine 6
+
+  # Set a viscosity source term on the velocity vector with x-component U
+  # The Reynolds number is Re = L*U/Nu = 1*1/1e-3 = 1000
+  SourceDiffusion {} U 1e-3
+  SourceDiffusion {} V 1e-3
+
+  # Stops the simulation if the maximum of the absolute value of the
+  # difference between the current U field and the U field 10 timesteps
+  # before is smaller than 1e-4.
+  #
+  # Stores this difference in the DU field (this can be used for
+  # monitoring the convergence of the simulation).
+  EventStop { istep = 10 } U 1e-4 DU
+
+  OutputScalarNorm { istep = 10 } du { v = DU }
+
+  # Pipes a bitmap PPM image representation of the velocity field at the end of the simulation
+  # into the ImageMagick converter "convert" to create the
+  # corresponding EPS file
+  OutputPPM { start = end } { convert -colors 256 ppm:- velocity.eps } {
+    v = Velocity
+  }
+
+  # At the end of the simulation, computes the values of the variables
+  # at the locations defined in files xprofile, yprofile and stores the
+  # results in files xprof, yprof
+  OutputLocation { start = end } xprof xprofile
+  OutputLocation { start = end } yprof yprofile
+
+  # At the end of the simulation calls the script generating the EPS
+  # files using gnuplot and files: xprof, yprof, xprof.ghia, yprof.ghia
+  EventScript { start = end } {
+    cat <<EOF | gnuplot
+    set term postscript eps lw 3 solid 20
+    set output 'xprof.eps'
+    set xlabel 'Y'
+    set ylabel 'U'
+    plot [-0.5:0.5]'xprof.ghia' u 1:2 title "Ghia et al." w p ps 2 pt 9, 'xprof' u 3:7 w l title "Gerris"
+    set output 'yprof.eps'
+    set xlabel 'X'
+    set ylabel 'V'
+    plot [-0.5:0.5]'yprof.ghia' u 1:2 title "Ghia et al." w p ps 2 pt 9, 'yprof' u 2:8 w l title "Gerris"
+EOF
+  }
+}
+GfsBox {
+
+  # Dirichlet boundary conditions for both components of the velocity on all sides:
+  # - non-slip (U = V = 0) on right, left and bottom boundaries
+  # - tangential velocity equal to 1 (U = 1) on top boundary
+
+  top = Boundary {
+    BcDirichlet U 1
+    BcDirichlet V 0
+  }
+  bottom = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+  right = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+  left = Boundary {
+    BcDirichlet U 0
+    BcDirichlet V 0
+  }
+}
diff --git a/test/lid/lid.sh b/test/lid/lid.sh
new file mode 100644
index 0000000..69de6ab
--- /dev/null
+++ b/test/lid/lid.sh
@@ -0,0 +1,17 @@
+if ! $donotrun; then
+    if gerris2D $1; then :
+    else
+	exit 1
+    fi
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('xprof',3,7) - Curve('xprof.ghia',1,2)).normi() > 2e-2 or \
+   (Curve('yprof',2,8) - Curve('yprof.ghia',1,2)).normi() > 1.7e-2:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/lid/xprof.ghia b/test/lid/xprof.ghia
new file mode 100644
index 0000000..e038a95
--- /dev/null
+++ b/test/lid/xprof.ghia
@@ -0,0 +1,17 @@
+-0.327052 -0.383699
+-0.397406 -0.297251
+-0.217948 -0.27788
+-0.428914 -0.222276
+-0.43629 -0.201989
+-0.444335 -0.181701
+-0.046595 -0.106804
+0.001598 -0.060949
+-0.49933 -0.000882
+0.118733 0.057217
+0.235193 0.186849
+0.352315 0.333239
+0.45404 0.466401
+0.461386 0.511382
+0.469392 0.574884
+0.476719 0.659554
+0.5 0.999118
diff --git a/test/lid/xprofile b/test/lid/xprofile
new file mode 100644
index 0000000..9aa9885
--- /dev/null
+++ b/test/lid/xprofile
@@ -0,0 +1,101 @@
+0 -0.5 0
+0 -0.49 0
+0 -0.48 0
+0 -0.47 0
+0 -0.46 0
+0 -0.45 0
+0 -0.44 0
+0 -0.43 0
+0 -0.42 0
+0 -0.41 0
+0 -0.4 0
+0 -0.39 0
+0 -0.38 0
+0 -0.37 0
+0 -0.36 0
+0 -0.35 0
+0 -0.34 0
+0 -0.33 0
+0 -0.32 0
+0 -0.31 0
+0 -0.3 0
+0 -0.29 0
+0 -0.28 0
+0 -0.27 0
+0 -0.26 0
+0 -0.25 0
+0 -0.24 0
+0 -0.23 0
+0 -0.22 0
+0 -0.21 0
+0 -0.2 0
+0 -0.19 0
+0 -0.18 0
+0 -0.17 0
+0 -0.16 0
+0 -0.15 0
+0 -0.14 0
+0 -0.13 0
+0 -0.12 0
+0 -0.11 0
+0 -0.1 0
+0 -0.09 0
+0 -0.08 0
+0 -0.07 0
+0 -0.06 0
+0 -0.05 0
+0 -0.04 0
+0 -0.03 0
+0 -0.02 0
+0 -0.01 0
+0 0 0
+0 0.01 0
+0 0.02 0
+0 0.03 0
+0 0.04 0
+0 0.05 0
+0 0.06 0
+0 0.07 0
+0 0.08 0
+0 0.09 0
+0 0.1 0
+0 0.11 0
+0 0.12 0
+0 0.13 0
+0 0.14 0
+0 0.15 0
+0 0.16 0
+0 0.17 0
+0 0.18 0
+0 0.19 0
+0 0.2 0
+0 0.21 0
+0 0.22 0
+0 0.23 0
+0 0.24 0
+0 0.25 0
+0 0.26 0
+0 0.27 0
+0 0.28 0
+0 0.29 0
+0 0.3 0
+0 0.31 0
+0 0.32 0
+0 0.33 0
+0 0.34 0
+0 0.35 0
+0 0.36 0
+0 0.37 0
+0 0.38 0
+0 0.39 0
+0 0.4 0
+0 0.41 0
+0 0.42 0
+0 0.43 0
+0 0.44 0
+0 0.45 0
+0 0.46 0
+0 0.47 0
+0 0.48 0
+0 0.49 0
+0 0.5 0
diff --git a/test/lid/yprof.ghia b/test/lid/yprof.ghia
new file mode 100644
index 0000000..f2a4470
--- /dev/null
+++ b/test/lid/yprof.ghia
@@ -0,0 +1,17 @@
+-0.500577 0.00069404
+-0.43768 0.275621
+-0.429602 0.290847
+-0.421523 0.303994
+-0.406521 0.326826
+-0.343624 0.371038
+-0.273803 0.330015
+-0.265724 0.32307
+-0.000289 0.0252893
+0.304962 -0.318994
+0.359781 -0.427191
+0.40652 -0.515279
+0.445182 -0.392034
+0.45326 -0.336623
+0.461339 -0.277749
+0.46884 -0.214023
+0.5 -6.20706e-17
diff --git a/test/lid/yprofile b/test/lid/yprofile
new file mode 100644
index 0000000..cd3e5d1
--- /dev/null
+++ b/test/lid/yprofile
@@ -0,0 +1,101 @@
+-0.5 0 0
+-0.49 0 0
+-0.48 0 0
+-0.47 0 0
+-0.46 0 0
+-0.45 0 0
+-0.44 0 0
+-0.43 0 0
+-0.42 0 0
+-0.41 0 0
+-0.4 0 0
+-0.39 0 0
+-0.38 0 0
+-0.37 0 0
+-0.36 0 0
+-0.35 0 0
+-0.34 0 0
+-0.33 0 0
+-0.32 0 0
+-0.31 0 0
+-0.3 0 0
+-0.29 0 0
+-0.28 0 0
+-0.27 0 0
+-0.26 0 0
+-0.25 0 0
+-0.24 0 0
+-0.23 0 0
+-0.22 0 0
+-0.21 0 0
+-0.2 0 0
+-0.19 0 0
+-0.18 0 0
+-0.17 0 0
+-0.16 0 0
+-0.15 0 0
+-0.14 0 0
+-0.13 0 0
+-0.12 0 0
+-0.11 0 0
+-0.1 0 0
+-0.09 0 0
+-0.08 0 0
+-0.07 0 0
+-0.06 0 0
+-0.05 0 0
+-0.04 0 0
+-0.03 0 0
+-0.02 0 0
+-0.01 0 0
+0 0 0
+0.01 0 0
+0.02 0 0
+0.03 0 0
+0.04 0 0
+0.05 0 0
+0.06 0 0
+0.07 0 0
+0.08 0 0
+0.09 0 0
+0.1 0 0
+0.11 0 0
+0.12 0 0
+0.13 0 0
+0.14 0 0
+0.15 0 0
+0.16 0 0
+0.17 0 0
+0.18 0 0
+0.19 0 0
+0.2 0 0
+0.21 0 0
+0.22 0 0
+0.23 0 0
+0.24 0 0
+0.25 0 0
+0.26 0 0
+0.27 0 0
+0.28 0 0
+0.29 0 0
+0.3 0 0
+0.31 0 0
+0.32 0 0
+0.33 0 0
+0.34 0 0
+0.35 0 0
+0.36 0 0
+0.37 0 0
+0.38 0 0
+0.39 0 0
+0.4 0 0
+0.41 0 0
+0.42 0 0
+0.43 0 0
+0.44 0 0
+0.45 0 0
+0.46 0 0
+0.47 0 0
+0.48 0 0
+0.49 0 0
+0.5 0 0
diff --git a/test/lonlat/coriolis/coriolis.gfs b/test/lonlat/coriolis/coriolis.gfs
new file mode 100644
index 0000000..92013a7
--- /dev/null
+++ b/test/lonlat/coriolis/coriolis.gfs
@@ -0,0 +1,56 @@
+# Title: Circular dam break on a rotating sphere
+#
+# Description:
+#
+# Similar test case but with rotation. See also test case of \cite{rossmanith2004}, Figure 7.
+#
+# \begin{figure}[htbp]
+# \caption{Solution to the rotating shallow-water equations computed
+# on a longitude-latitude grid in the domain
+# $[-75^\circ,75^\circ]\times[-75^\circ,75^\circ]$ with $256\times
+# 256$ points. The Coriolis parameter is set to $f=10$. The solution
+# is shown at times (a) $t=0.4$, (b) $t=0.8$, and (c) $t=1.2$.
+# }
+# \begin{center}
+# \begin{tabular}{cc}
+# (a) \includegraphics[width=0.45\hsize]{isolines-0.4.eps} &
+# (b) \includegraphics[width=0.45\hsize]{isolines-0.8.eps} \\
+# \multicolumn{2}{c}{(c) \includegraphics[width=0.45\hsize]{isolines-1.2.eps}}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D -m coriolis.gfs
+# Version: 090924
+# Required files: isolines.gfv
+# Running time: 5 minutes
+# Generated files: isolines-0.4.eps isolines-0.8.eps isolines-1.2.eps
+#
+Define LENGTH (150./180.*M_PI)
+
+1 0 GfsRiver GfsBox GfsGEdge {} {
+    PhysicalParams { L = LENGTH }
+    MetricLonLat M 1.
+    Refine 8
+    InitFraction P (0.2 - acos(cos(x*M_PI/180.)*cos(y*M_PI/180.)))
+    Init {} { P = 0.2 + 1.8*P/LENGTH }
+    Time { end = 1.4 }
+    SourceCoriolis 10.*sin(y*M_PI/180.)
+    OutputTime { istep = 10 } stderr
+    OutputSimulation { step = 0.4 } sim-%g.gfs
+    OutputSimulation { step = 0.4 } sim-%g.txt { variables = U,V,P format = text }
+#    OutputSimulation { istep = 10 } stdout
+    EventScript { start = end } {
+	for i in 0.4 0.8 1.2; do
+	    echo "Save stdout { format = EPS line_width = 0.5 }" | \
+		gfsview-batch2D sim-$i.gfs isolines.gfv > isolines-$i.eps
+	done
+    }
+}
+GfsBox {
+    right = Boundary { BcNeumann U 0 }
+    left = Boundary { BcNeumann U 0 }
+    top = Boundary { BcNeumann V 0 }
+    bottom = Boundary { BcNeumann V 0 }
+}
diff --git a/test/lonlat/coriolis/isolines.gfv b/test/lonlat/coriolis/isolines.gfv
new file mode 100644
index 0000000..2da075e
--- /dev/null
+++ b/test/lonlat/coriolis/isolines.gfv
@@ -0,0 +1,33 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 25.764
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 20
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
diff --git a/test/lonlat/isolines.gfv b/test/lonlat/isolines.gfv
new file mode 100644
index 0000000..2da075e
--- /dev/null
+++ b/test/lonlat/isolines.gfv
@@ -0,0 +1,33 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 25.764
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 20
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+}
diff --git a/test/lonlat/lonlat.gfs b/test/lonlat/lonlat.gfs
new file mode 100644
index 0000000..ee8a751
--- /dev/null
+++ b/test/lonlat/lonlat.gfs
@@ -0,0 +1,121 @@
+# Title: Circular dam break on a sphere
+#
+# Description:
+#
+# An initial circular cylinder collapses and creates shock and
+# rarefaction waves. The initial condition are radially-symmetric and
+# should remain so. The problem is discretised using
+# longitude-latitude spherical coordinates. Deviations from radial
+# symmetry are a measure of the accuracy of treatment of geometric
+# source terms.
+#
+# This test case was proposed by \cite{rossmanith2004}, Figures 5 and 6.
+#
+# \begin{figure}[htbp]
+# \caption{\label{height}Solution to the shallow-water equations computed on a
+# longitude-latitude grid in the domain
+# $[-75^\circ,75^\circ]\times[-75^\circ,75^\circ]$ with $256\times
+# 256$ points. The solution is shown at times (a) $t=0.3$, (b)
+# $t=0.6$, and (c) $t=0.9$. The contours do not appear circular
+# because the solution has been projected down to a plane.}
+# \begin{center}
+# \begin{tabular}{cc}
+# (a) \includegraphics[width=0.45\hsize]{isolines-0.3.eps} &
+# (b) \includegraphics[width=0.45\hsize]{isolines-0.6.eps} \\
+# \multicolumn{2}{c}{(c) \includegraphics[width=0.45\hsize]{isolines-0.9.eps}}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp] 
+# \caption{Scatter plot of the (radial) solution shown in Figure
+# \ref{height}. The green line is the average solution. The solution
+# is shown at times (a) $t=0.3$, (b) $t=0.6$, and (c) $t=0.9$.}
+# \begin{center}
+# \begin{tabular}{c}
+# (a) \includegraphics[width=0.8\hsize]{p-0.3.eps} \\
+# (b) \includegraphics[width=0.8\hsize]{p-0.6.eps} \\
+# (c) \includegraphics[width=0.8\hsize]{p-0.9.eps}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D -m lonlat.gfs
+# Version: 090924
+# Required files: isolines.gfv
+# Running time: 5 minutes
+# Generated files: isolines-0.3.eps isolines-0.6.eps isolines-0.9.eps p-0.3.eps p-0.6.eps p-0.9.eps
+#
+Define LENGTH (150./180.*M_PI)
+
+1 0 GfsRiver GfsBox GfsGEdge {} {
+    PhysicalParams { L = LENGTH }
+    MetricLonLat M 1.
+    Refine 8
+    InitFraction P (0.2 - acos(cos(x*M_PI/180.)*cos(y*M_PI/180.)))
+    Init {} { P = 0.2 + 1.8*P/LENGTH }
+    Time { end = 0.9 }
+    OutputTime { istep = 10 } stderr
+    OutputSimulation { step = 0.3 } sim-%g.gfs
+    OutputSimulation { step = 0.3 } sim-%g.txt { variables = U,V,P format = text }
+    OutputScalarSum { istep = 1 } sp { v = P }
+#    OutputSimulation { istep = 10 } stdout
+    EventScript { start = end } {
+	status=0
+	for i in 0.3 0.6 0.9; do
+	    if awk 'BEGIN { n1 = 0; pi = 3.14159265359 }{
+              if ($1 != "#") {
+                c = cos($1*pi/180.)*cos($2*pi/180.);
+                d = atan2(sqrt(1. - c*c),c)*180./pi
+                i = int(d*2.)
+                x[i] += d
+                y[i] += $6
+                n[i]++
+                x1[n1] = d;
+                y1[n1++] = $6;
+              }
+            }END {
+              for (i = 0; i <= 180; i++)
+                if (n[i] > 0)
+                  print x[i]/n[i], y[i]/n[i], n[i];
+              sum = 0.;
+              for (i = 0; i < n1; i++) {
+                j = int(x1[i]*2.)
+                d = y1[i] - y[j]/n[j];
+                sum += d*d;
+              }
+              scatter = sqrt(sum/n1);
+              if (scatter > 0.012) {
+                print scatter > "/dev/stderr";
+                exit (1);
+              }
+            }' < sim-$i.txt > prof-$i.txt ; then :
+	    else
+		status=$GFS_STOP;
+	    fi
+
+	    cat <<EOF | gnuplot
+rdist(x,y)=acos(cos(x*pi/180.)*cos(y*pi/180.))*180./pi
+cdist(x,y)=sqrt(x*x+y*y)
+set xlabel 'Angular distance (degree)'
+set ylabel 'Surface height'
+set xtics 0,22.5,90
+set ytics 0,0.25,0.75
+set term postscript eps color lw 2 solid 20
+set output 'p-$i.eps'
+plot [0:90][0:0.75]'sim-$i.txt' u (rdist(\$1,\$2)):6 ps 0.25 pt 6 t '', 'prof-$i.txt' w l lw 2 t ''
+EOF
+
+	    echo "Save stdout { format = EPS line_width = 0.5 }" | \
+		gfsview-batch2D sim-$i.gfs isolines.gfv > isolines-$i.eps
+	done
+	exit $status
+    }
+}
+GfsBox {
+    right = Boundary { BcNeumann U 0 }
+    left = Boundary { BcNeumann U 0 }
+    top = Boundary { BcNeumann V 0 }
+    bottom = Boundary { BcNeumann V 0 }
+}
diff --git a/test/merging/levels.gfv b/test/merging/levels.gfv
new file mode 100644
index 0000000..52abaa9
--- /dev/null
+++ b/test/merging/levels.gfv
@@ -0,0 +1,22 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = 8
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} Level {
+  amin = 1
+  amax = 1
+  cmap = Jet
+}
diff --git a/test/merging/merging.gfs b/test/merging/merging.gfs
new file mode 100644
index 0000000..a09b598
--- /dev/null
+++ b/test/merging/merging.gfs
@@ -0,0 +1,153 @@
+# Title: Convergence for the three-way vortex merging problem
+#
+# Description:
+#
+# Another of the test cases presented in Popinet \cite{popinet2003},
+# initially used by Almgren et al. \cite{almgren98}, this convergence
+# test illustrates the second-order accuracy of Gerris when refinement
+# is placed appropriately, either through static refinement or dynamic
+# adaptive refinement.
+#
+# Four vortices are placed in the unit-square, centred at $(0,0)$,
+# $(0.09,0)$, $(-0.045,0.045\sqrt{3})$ and $(-0.045,$ $-0.045\sqrt{3})$
+# and of strengths $-150$, $50$, $50$, $50$ respectively. The profile of
+# each vortex centred around $(x_i,y_i)$ is
+# $$
+# {1+\tanh(100(0.03-r_i))\over 2},
+# $$
+# where $r_i=\sqrt{(x-x_i)^2+(y-y_i)^2}$. To initialise the velocity
+# field, we use this vorticity as the source term in the Poisson
+# equation for the streamfunction $\psi$
+# $$
+# \nabla^2\psi=\|\nabla\times{\bf U}\|.
+# $$
+# Each component of the velocity field is then calculated from the
+# streamfunction. No-flow boundary conditions are used on the four sides
+# of the domain and the simulations are ran to $t=0.25$ using a CFL of
+# 0.9.
+#
+# Two different discretisations are used, each time with up to $L$
+# levels of refinement: a grid using static refinement in concentric
+# circles of decreasing radius and a grid using dynamic adaptive
+# refinement. The ``circle'' grid is constructed by starting from a
+# uniform grid with four levels of refinement and by successively adding
+# one level to all the cells contained within circles centred on the
+# origin and of radii:
+# \begin{itemize}
+# \item $L=6$: 0.25, 0.15
+# \item $L=7$: 0.25, 0.2, 0.15
+# \item $L=8$: 0.25, 0.2, 0.175, 0.15
+# \item $L=9$: 0.25, 0.2, 0.175, 0.1625, 0.15
+# \end{itemize}
+# For the dynamically refined grid, the vorticity-based criterion is
+# applied at every timestep with a threshold $\tau=4\times10^{-3}$. As
+# we do not have an analytical solution for this problem, Richardson
+# extrapolation is used.
+#
+# Figure \ref{vorticity} illustrates the evolution of the vorticity
+# and of the adaptively refined grid for $L=8$. The most refined level
+# closely follows the three outer vortices as they orbit the central
+# one. Far from the vortices, a very coarse mesh is used ($l=3$). One
+# may note a few isolated patches of refinement scattered at the
+# periphery of the outer vortices. They are due to the numerical noise
+# added to the vorticity by the interpolation procedure necessary to
+# fill in velocity values for newly created cells. This could be
+# improved by using higher-order interpolants.
+#
+# Table \ref{convergence} summarises the results obtained for the
+# first twelve calculations. For fine enough grids close to
+# second-order convergence is obtained for both norms and for the two
+# discretisations used. The norms of the error on the various grids
+# are also comparable for a given resolution.
+#
+# \begin{table}
+# \caption{\label{convergence}Errors and convergence orders in the $x$-component of the
+# velocity for the four-way vortex merging problem. The reference
+# solution values are given in blue.}
+# \begin{center}
+# \input{convergence.tex}
+# \end{center}
+# \end{table}
+#
+# \begin{figure}
+# \caption{\label{vorticity}Contour plots of vorticity (left) and adaptive grids used
+# (right) for the four-way vortex merging calculation.}
+# \begin{center}
+# \begin{tabular}{cc}
+# \includegraphics*[width=0.3\hsize]{tv_0_05.eps} &
+# \includegraphics*[width=0.3\hsize]{tm_0_05.eps} \\
+# \multicolumn{2}{c}{$t=0.05$} \\
+# \\
+# \includegraphics*[width=0.3\hsize]{tv_0_15.eps} &
+# \includegraphics*[width=0.3\hsize]{tm_0_15.eps} \\
+# \multicolumn{2}{c}{$t=0.15$} \\
+# \\
+# \includegraphics*[width=0.3\hsize]{tv_0_25.eps} &
+# \includegraphics*[width=0.3\hsize]{tm_0_25.eps} \\
+# \multicolumn{2}{c}{$t=0.25$}
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh merging.sh merging.gfs
+# Version: 0.6.4
+# Required files: merging.sh levels.gfv vorticity.gfv sim.err.ref simc.err.ref
+# Running time: 3 minutes
+# Generated files: convergence.tex tv_0_05.eps tm_0_05.eps tv_0_15.eps tm_0_15.eps tv_0_25.eps tm_0_25.eps
+#
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 0.25 }
+  AdvectionParams { cfl = 0.9 }
+  ApproxProjectionParams { tolerance = 1e-5 }
+  ProjectionParams { tolerance = 1e-5 }
+  Refine {
+    double r = sqrt(x*x + y*y);
+    switch (LEVEL) {
+    case 6: return r > 0.25 ? 4 : r > 0.15 ? 5 : 6;
+    case 7: return r > 0.25 ? 4 : r > 0.2 ? 5 : r > 0.15 ? 6 : 7;
+    case 8: return r > 0.25 ? 4 : r > 0.2 ? 5 : r > 0.175 ? 6 : r > 0.15 ? 7 : 8;
+    case 9: return r > 0.25 ? 4 : r > 0.2 ? 5 : r > 0.175 ? 6 : r > 0.1625 ? 7 : r > 0.15 ? 8 : 9;
+    }
+  }
+  InitVorticity {} {
+    double vortex (double xo, double yo, double s) {
+      double r = sqrt ((x - xo)*(x - xo) + (y - yo)*(y - yo));
+      return s*(1. + tanh (100.*(0.03 - r)))/2.;
+    }
+    return vortex (0., 0., -150.) + 
+           vortex (0.09, 0., 50.) + 
+           vortex (-0.045, 0.0779422863406, 50.) +
+           vortex (-0.045, -0.0779422863406, 50.);
+  }
+  AdaptVorticity { istep = 1 } { maxlevel = LEVEL cmax = 4e-3 }
+  OutputSimulation { start = 0.05 } stdout
+  EventScript { start = 0.05 } {
+    echo Clear
+    cat levels.gfv
+    echo Save tm_0_05.eps { format = EPS line_width = 0.1 }
+    echo Clear
+    cat vorticity.gfv
+    echo Save tv_0_05.eps { format = EPS line_width = 0.1 }
+  }
+  OutputSimulation { start = 0.15 } stdout
+  EventScript { start = 0.15 } {
+    echo Clear
+    cat levels.gfv
+    echo Save tm_0_15.eps { format = EPS line_width = 0.1 }
+    echo Clear
+    cat vorticity.gfv
+    echo Save tv_0_15.eps { format = EPS line_width = 0.1 }
+  }
+  OutputSimulation { start = 0.25 } stdout
+  EventScript { start = 0.25 } {
+    echo Clear
+    cat levels.gfv
+    echo Save tm_0_25.eps { format = EPS line_width = 0.1 }
+    echo Clear
+    cat vorticity.gfv
+    echo Save tv_0_25.eps { format = EPS line_width = 0.1 }
+  }
+  OutputSimulation { start = 0.25 } SIM
+}
+GfsBox {}
diff --git a/test/merging/merging.sh b/test/merging/merging.sh
new file mode 100644
index 0000000..e906190
--- /dev/null
+++ b/test/merging/merging.sh
@@ -0,0 +1,90 @@
+if ! $donotrun; then
+    if sed "s/LEVEL/8/g" < $1 | \
+       sed "s/SIM/sim-8/g" | \
+       gerris2D - | gfsview-batch2D; then :
+    else
+	exit 1
+    fi
+
+    for level in 6 7 9; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+           sed "s/SIM/sim-$level/g" | \
+           gerris2D - > /dev/null; then :
+	else
+	    exit 1
+	fi
+    done
+
+    for level in 6 7 8 9; do
+	if sed "s/LEVEL/$level/g" < $1 | \
+           sed "s/AdaptVorticity/# AdaptVorticity/g" | \
+           sed "s/SIM/simc-$level/g" | \
+           gerris2D - > /dev/null; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+for s in sim simc; do
+    rm -f $s.err
+    for level in 6 7 8; do
+	level1=`expr $level + 1`
+	echo -n "$level " >> $s.err
+	if gfscompare2D -v $s-$level $s-$level1 U 2>&1 | \
+	    awk '{if ($1 == "total") print $6 " " $8;}' >> $s.err; then :
+	else
+	    exit 1
+	fi
+    done
+done
+
+if cat <<EOF | python > convergence.tex ; then :
+from check import *
+from sys import *
+from math import *
+
+print r"""\begin{tabular}{|c|c|c|c|c|c|}\hline
+Domain   & \multicolumn{5}{c|}{\$L_2\$}\\\ \hline
+         & \$L=6\$   & \$O_2\$ & \$L=7\$    & \$O_2\$ & \$L=8\$  \\\ \hline"""
+
+def order(r,color='black'):
+   for i in range(0,len(r.l)-1):
+     y0,y1 = r.l[i][1],r.l[i+1][1]
+     print '& {\color{%s}%.2e} & {\color{%s}%4.2f}' % (color, y0, color, log(y0/y1)/log(2.)),
+   print '& {\color{%s}%.2e}' % (color, r.l[i+1][1]), r'\\\'
+
+print 'Circle',
+order(Curve('simc.err',1,2))
+order(Curve('simc.err.ref',1,2), 'blue')
+print 'Adaptive',
+order(Curve('sim.err',1,2))
+order(Curve('sim.err.ref',1,2), 'blue')
+
+print r"""\hline
+Domain   & \multicolumn{5}{c|}{\$L_\infty\$} \\\ \hline
+         &  \$L=6\$   & \$O_\infty\$ & \$L=7\$   & \$O_\infty\$ & \$L=8\$ \\\ \hline"""
+
+print 'Circle',
+order(Curve('simc.err',1,3))
+order(Curve('simc.err.ref',1,3), 'blue')
+print 'Adaptive',
+order(Curve('sim.err',1,3))
+order(Curve('sim.err.ref',1,3), 'blue')
+
+print r"\hline\end{tabular}"
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('sim.err',1,2) - Curve('sim.err.ref',1,2)).max() > 1e-6 or\
+   (Curve('simc.err',1,3) - Curve('simc.err.ref',1,3)).max() > 1e-6:
+  exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/merging/sim.err.ref b/test/merging/sim.err.ref
new file mode 100644
index 0000000..21eba36
--- /dev/null
+++ b/test/merging/sim.err.ref
@@ -0,0 +1,3 @@
+6 2.609e-02 4.564e-01
+7 1.071e-02 1.924e-01
+8 2.837e-03 4.519e-02
diff --git a/test/merging/simc.err.ref b/test/merging/simc.err.ref
new file mode 100644
index 0000000..e83e0fc
--- /dev/null
+++ b/test/merging/simc.err.ref
@@ -0,0 +1,3 @@
+6 2.634e-02 4.563e-01
+7 1.058e-02 1.882e-01
+8 2.691e-03 4.873e-02
diff --git a/test/merging/vorticity.gfv b/test/merging/vorticity.gfv
new file mode 100644
index 0000000..c3a7443
--- /dev/null
+++ b/test/merging/vorticity.gfv
@@ -0,0 +1,33 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = 8
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} Vorticity {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 17
+}
+Boundaries {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = 8
+}
diff --git a/test/nz/bath.gts b/test/nz/bath.gts
new file mode 100644
index 0000000..c2e048a
--- /dev/null
+++ b/test/nz/bath.gts
@@ -0,0 +1,28678 @@
+4790 14338 9549 GtsSurface GtsFace GtsEdge GtsVertex
+0.3451344905 -8.730459598e-05 -0.446294
+0.3624423858 0.01685363459 -0.442784
+0.3516275209 -0.008120873138 -0.477514
+0.05285171953 -0.06664108081 0.00062
+0.04599628715 -0.06317421995 0.00062
+0.04886727341 -0.0671151552 0.00062
+0.01690420945 -0.07633392018 0.00062
+0.01570319756 -0.0759521268 -0.000648
+0.0143755659 -0.07672322959 0.000612
+0.2400202103 -0.5815862475 -0.003066
+0.2306217651 -0.5855598924 -0.002526
+0.2311775762 -0.5643968917 -0.003684
+0.09406943404 -0.06885489612 0.000616
+0.09435346608 -0.06997810487 -0.000938
+0.09345542456 -0.0694260657 -0.001078
+0.8738353702 0.04014279389 -0.072202
+0.8480579764 0.03425717981 -0.073444
+0.8449067731 0.007208984554 -0.0756
+-0.52766537 -0.0476957138 -0.14546
+-0.553979437 -0.06813257572 -0.165458
+-0.5060428429 -0.11232722 -0.150042
+-0.008038642829 -0.0866469038 0.00062
+-0.00592370856 -0.08159933604 -0.00138
+-0.005053181461 -0.08601204409 -0.00138
+-0.1121349845 0.1652994804 -0.007062
+-0.1116055982 0.1540134057 -0.008438
+-0.1031030519 0.159566355 -0.008904
+-0.2579562128 -0.1641692562 -0.011278
+-0.2715616123 -0.1697008921 -0.021602
+-0.2684712036 -0.1547169724 -0.020192
+-0.1393187306 0.7685157023 0.00062
+-0.1401681769 0.7712735641 0.00042
+-0.1436153264 0.768806042 0.00042
+0.0043673514 -0.04710594415 0.00062
+0.005812314195 -0.04646985625 -0.001076
+0.002593265809 -0.04395399237 0.00062
+-0.4350433933 0.348685445 -0.03938
+-0.4391275139 0.3238283307 -0.149362
+-0.4160428463 0.3371349351 -0.046582
+0.2536382058 0.5971323608 -0.01444
+0.2607783485 0.6143348048 -0.0143
+0.264597253 0.592284208 -0.017248
+0.5302997213 0.3780466628 -0.506042
+0.4905815315 0.3256881325 -0.473512
+0.4859200325 0.3647617858 -0.47356
+-0.02074628118 -0.003128718443 -0.003428
+-0.01324727699 -0.002075746333 0.00062
+-0.01568577061 0.002663585597 0.000616
+0.03971708488 -0.09922557618 0.00062
+0.03882731541 -0.1025905099 0.00062
+0.0406347177 -0.1008341685 -0.001252
+0.06898439648 -0.06890929905 -0.00538
+0.07166882288 -0.06689179696 -0.00538
+0.06900050785 -0.06527344964 0.000598
+0.2917356752 -0.4251925441 -0.054524
+0.2827281062 -0.4442809803 -0.023946
+0.2715469258 -0.4285701248 -0.025764
+-0.1647714588 -0.3951824705 -0.003466
+-0.1725861322 -0.3888672686 -0.00572
+-0.1762435149 -0.3993148013 -0.006226
+0.2517680434 0.7901759558 -0.003926
+0.2498935809 0.7977716924 0.000618
+0.2434788004 0.7912723229 -0.003048
+-0.4872663631 0.2269501832 -0.081094
+-0.5159047977 0.2483484387 -0.214982
+-0.5175215683 0.2075808611 -0.19489
+0.2224270154 0.5780724944 -0.008918
+0.2086046477 0.5686272447 -0.005504
+0.2125847748 0.5777983698 -0.007868
+0.3067582596 -0.6328120964 -0.001318
+0.3030870473 -0.6347112627 0.00062
+0.3060270051 -0.6400942173 0.00062
+0.08625811345 -0.03726735315 0.00062
+0.08645055123 -0.03513998332 -0.003928
+0.08417748739 -0.03582132183 0.00062
+-0.1757616569 -0.4121573181 -0.004568
+-0.1833366779 -0.40512749 -0.008284
+-0.1869459347 -0.4121026655 -0.00964
+-0.1169765312 0.8053054214 -0.00239
+-0.1122523556 0.7962471383 -0.003488
+-0.1229055081 0.7974492115 -0.00338
+0.1882348205 -0.5210844878 0.00062
+0.1890981792 -0.5103695965 0.00062
+-0.1233330672 -0.5531733428 0.00038
+-0.006980574151 -0.04330737763 0.00062
+-0.0050627606 -0.04140064545 -0.000464
+-0.004304152017 -0.04413058839 -0.002586
+0.03442655978 -0.04991897752 -0.005112
+0.03484225066 -0.04832282024 -0.005274
+0.03301160509 -0.04954103249 -0.00875
+0.1381748955 -0.07680955284 -0.017472
+0.142818299 -0.06540536233 -0.023232
+0.1314727652 -0.06640653484 -0.020168
+-0.02698362551 -0.03658657286 -0.007588
+-0.03656578006 -0.03805163867 -0.011236
+-0.02980012643 -0.0447508161 -0.009688
+0.270846353 -0.4872865087 -0.013422
+0.2589759667 -0.4913942427 -0.00924
+0.2606891496 -0.4808825242 -0.011512
+-0.4232105622 0.3891045298 -0.108598
+-0.4044450916 0.379400058 -0.033638
+-0.4025623175 0.3991300472 -0.03546
+0.0737696106 0.964896881 -0.00775
+0.05736806368 0.9641822827 -0.03201
+0.06560498875 0.95466813 -0.01528
+0.2039950352 0.5588722061 -0.004058
+0.1917345019 0.5580390872 -0.002478
+0.1986753955 0.5486373669 -0.001994
+0.2612971764 0.7034498818 0.000492
+0.2628345694 0.6952177673 -0.00453
+0.2696949166 0.701334417 -0.003244
+0.6607718152 -0.1844878336 -0.056236
+0.6315126144 -0.1857473707 -0.066598
+0.642684176 -0.1653178972 -0.067516
+-0.1813801226 -0.4211239787 -0.003494
+-0.1892526749 -0.427050688 -0.006092
+-0.1911981393 -0.4188517745 -0.012092
+-0.2366685024 0.1760773923 -0.020436
+-0.2297170013 0.1875718825 -0.01817
+-0.2362253671 0.1982062324 -0.014464
+-0.1353410628 0.09256615719 -0.017124
+-0.1335246015 0.107084639 -0.02022
+-0.1453212048 0.1141888705 -0.020336
+0.02845940334 0.8228093259 0.000416
+0.02965421487 0.824418224 0.00022
+0.02737178613 0.8253398031 0.00062
+0.1871869073 -0.1250273588 -0.025456
+0.1746278297 -0.1255390648 -0.008092
+0.177769522 -0.1147451431 -0.020972
+-0.3590883947 0.4743355284 -0.01811
+-0.367579203 0.4628913388 -0.020944
+-0.3734785815 0.4748568846 -0.019864
+0.3028429201 0.05435892837 0.00062
+0.2435600688 0.0221163906 0.00062
+0.2950066089 0.02980671249 0.00062
+-0.1632504347 0.7786565276 0.00052
+-0.1621496741 0.7806727604 0.000616
+-0.1653264815 0.779554007 0.00052
+0.241584942 -0.6258871313 0.00062
+0.2367318936 -0.6212740625 0.00062
+0.2397970944 -0.6218522792 0.000618
+-0.1443383706 -0.78774766 -0.01189
+-0.1324713404 -0.7864634958 -0.00338
+-0.1344813483 -0.7965578683 -0.003768
+0.02536193648 -0.0265582743 0.000616
+0.0281356427 -0.02750757838 0.00062
+0.0234387408 -0.02976650397 0.000586
+0.1039393171 0.05384931428 -0.034554
+0.1049057165 0.04421766052 -0.036464
+0.0953878396 0.04885538732 -0.031078
+0.01890037836 -0.05809760893 0.00062
+0.02250288099 -0.05767851918 0.00062
+0.01998603828 -0.05233635455 -0.00138
+0.4925738692 -0.2471245002 -0.039958
+0.476540521 -0.2310152184 -0.084498
+0.4712387698 -0.2516350015 -0.064914
+-0.1507399256 0.1689827905 -0.009322
+-0.1609853995 0.1707863849 -0.009468
+-0.1569212243 0.1590302111 -0.011166
+0.04006950149 -0.08324637462 -0.001778
+0.04005404471 -0.08244648666 -0.00235
+0.03876750095 -0.08143907548 0.00062
+0.08711530089 -0.04196156139 -0.005874
+0.08457262535 -0.04231897605 0.000602
+0.08536763136 -0.04405677808 -0.00692
+0.2179252518 0.6368826523 -0.006056
+0.2210753459 0.6258022882 -0.008724
+0.229038002 0.6324380005 -0.009402
+0.3648249589 0.1731722107 -0.234898
+0.3557898061 0.1694487777 -0.167404
+0.3568647143 0.1815723241 -0.177362
+-0.04187641896 -0.1249396871 -0.005606
+-0.03221335634 -0.1233326921 -0.004318
+-0.03602388932 -0.1149676396 -0.005712
+-0.1465911797 -0.5667533439 -0.011892
+-0.1373022934 -0.5736426942 -0.007538
+-0.1368456031 -0.5625519289 -0.005234
+0.03392856174 -0.003998272187 -0.007722
+0.04573458903 0.00210482613 -0.011974
+0.03509393037 0.007484188885 -0.013176
+-0.2745385598 -0.2247292418 -0.025742
+-0.2481245388 -0.2233304565 -0.01938
+-0.2575763627 -0.2043771216 -0.01938
+0.2904843716 0.7473161781 -0.008798
+0.2993501155 0.7471285355 -0.007014
+0.2945189973 0.7374858309 -0.006962
+0.1128075275 0.08151632535 -0.024254
+0.1081167869 0.07235707271 -0.022216
+0.1041854503 0.07924823907 -0.022728
+0.08662251626 -0.03953778103 -0.00938
+0.08519721079 -0.03861533528 0.00062
+0.1795835766 -0.2340884906 0.00062
+0.1848552131 -0.2467789754 0.00062
+0.1871826384 -0.2390182464 0.00062
+0.3858448228 0.03285367064 -0.457502
+0.414930787 0.03560742418 -0.5349
+0.3935515799 0.0219198576 -0.509768
+-0.1958885444 -0.3741300006 -0.016516
+-0.1811970263 -0.3879445454 -0.008328
+-0.2048916003 -0.3828521374 -0.02073
+-0.1320555622 0.7993034243 -0.005346
+-0.1299915016 0.7918983826 -0.003396
+-0.1399780421 0.8015928237 -0.007638
+0.3020816664 0.6149633261 -0.023736
+0.3114533257 0.6270351176 -0.02025
+0.3013373689 0.6348037221 -0.016296
+0.0974752023 -0.03500080817 0.00062
+0.0984987848 -0.03622953348 -0.00074
+0.09927111839 -0.03584632774 -0.003772
+0.03125389561 -0.04849383946 -0.007528
+0.03113852051 -0.05018614417 0.000612
+0.02896617362 -0.04890723697 -0.00907
+0.3210203244 0.1315858892 -0.004438
+0.3199050185 0.1372677756 -0.003398
+0.3178372099 0.1328776021 0.00062
+-0.01943408625 -0.02800996867 -0.001152
+-0.02096661456 -0.0277622441 -0.00225
+-0.02000772556 -0.02942307609 -0.001402
+0.01820561895 0.8205156388 0.00062
+0.02070646568 0.8215972829 0.00062
+0.01924608516 0.8265977441 -0.00195
+0.08037422592 -0.05586965279 -0.00655
+0.07813389377 -0.05528198799 0.000596
+0.07818731389 -0.05769856743 -0.00538
+0.3276287622 -0.5052585943 -0.036728
+0.3234359174 -0.4885453975 -0.023562
+0.3084208047 -0.5014001646 -0.102232
+-0.4607030506 -0.002303171069 -0.049994
+-0.487309127 -0.00022677054 -0.059482
+-0.4716646943 -0.02370606573 -0.057966
+-0.1643094068 0.182205442 -0.008016
+-0.3119942177 -0.365139346 -0.037284
+-0.2825883775 -0.3451290213 -0.031432
+-0.3166373276 -0.3301939261 -0.045852
+0.2899015741 -0.1593842538 -0.402978
+0.2978444749 -0.1156746404 -0.429866
+0.3153377837 -0.1674069157 -0.467692
+0.7590611901 -0.06180144368 -0.051324
+0.7939056866 -0.08508675022 -0.049354
+0.8123675927 -0.06918933067 -0.054768
+0.2490421718 -0.5222470329 -0.005048
+0.2519315269 -0.5106494485 -0.005628
+0.2412707697 -0.5134310969 -0.005946
+0.3893191217 0.1305223982 -0.26123
+0.3791955011 0.1236537142 -0.239814
+0.3921071909 0.1184320181 -0.297084
+0.1414354462 -0.1088792089 -0.006202
+0.147102238 -0.09796368164 -0.010282
+0.1358424138 -0.1000939152 -0.00725
+0.3973001701 0.1967017211 -0.215476
+0.3876873099 0.1767125123 -0.22346
+0.377489194 0.1960675915 -0.238196
+-0.01618312443 0.8775634565 -0.037342
+-0.005744269065 0.8696631151 -0.020976
+-0.003625340103 0.8789752393 -0.033982
+0.4028859103 -0.005345080788 -0.516586
+0.3869991659 0.0001219262217 -0.514308
+0.3773384131 -0.03492514706 -0.480222
+0.1161007385 0.09823063039 -0.015822
+0.1225294573 0.09572250348 0.000598
+0.1143481581 0.09132675878 -0.020088
+-0.1562796793 -0.6525624658 -0.039638
+-0.1457685416 -0.6653754958 -0.045448
+-0.1391792056 -0.6557880226 -0.03216
+-0.2473457181 -0.750023299 -0.144204
+-0.2627246032 -0.7667434097 -0.16788
+-0.2296452319 -0.7604830001 -0.111388
+-0.1540529473 -0.5961619316 -0.025838
+-0.1439930936 -0.6070753932 -0.023216
+-0.1410429292 -0.5948577209 -0.0177
+-0.01102700306 -0.08181438126 -0.002648
+-0.2065783987 -0.3449087136 -0.019642
+-0.2073062631 -0.3572092008 -0.020206
+-0.1973106119 -0.351096033 -0.0122
+-0.238356347 -0.06080730033 -0.01864
+-0.2210419757 -0.06915101294 -0.015908
+-0.2154688577 -0.05299000012 -0.014738
+-0.09188266568 -0.06573958178 -0.009184
+-0.09411126305 -0.04826757321 -0.00942
+-0.08282487755 -0.05788196247 -0.00948
+0.2092749056 -0.3039281626 -0.049858
+0.2214478351 -0.2930940825 -0.191986
+0.2216854785 -0.3148200398 -0.208698
+-0.1670401525 -0.7596351826 -0.025836
+-0.1711864636 -0.7734731318 -0.028866
+-0.182269138 -0.7609334266 -0.03255
+-0.1513645772 0.1471060207 -0.013418
+-0.1637579301 0.1490664531 -0.013756
+0.1940540431 0.6183261959 -0.002388
+0.212884449 0.6203027504 -0.00704
+0.1970851265 0.6091144024 -0.003592
+0.5475459634 -0.2026500878 -0.094384
+0.5185016995 -0.2089499482 -0.10092
+0.5275932142 -0.1822653276 -0.115782
+-0.0161092373 -0.006280770477 -0.003318
+-0.01937922482 -0.007377082824 -0.001788
+0.2481525086 0.7612008351 0.000576
+0.2541187745 0.755141447 0.00062
+0.2551618091 0.74922506 0.00062
+0.2756808679 -0.01646637856 -0.048444
+0.2742267798 -0.006243725437 0.000618
+0.2841181153 -0.01336951617 -0.0556
+0.02191116499 -0.01011943944 0.000608
+0.01680288031 -0.01425678443 -0.004524
+0.0136944555 -0.009500958679 -0.00575
+0.3651407945 -0.02959003843 -0.49648
+-0.2829666595 0.5380728464 0.00062
+-0.2896070298 0.5331662989 0.00062
+-0.2888003815 0.5302628389 0.0002
+0.2157382983 0.5989637867 -0.009618
+0.2165432279 0.5875659153 -0.009472
+0.2262600097 0.5846388939 -0.009824
+-0.05394718942 -0.1735871668 0.00055
+-0.07706888917 -0.1641554052 0.00062
+-0.06039013849 -0.1691630272 0.00062
+0.04074299647 -0.08482788323 -0.00138
+0.0406420487 -0.0841870321 -0.00138
+0.04001471814 -0.08474415839 0.00062
+0.3047801007 0.01325109963 -0.050954
+0.296744572 0.01230789914 -0.0242
+0.3009779607 0.01820424555 -0.020104
+0.3172020478 0.169927564 -0.00298
+0.3155096707 0.1766219966 -0.003824
+0.3120102694 0.1686207308 0.00062
+0.03114136151 -0.04600692051 -0.004774
+0.02984025365 -0.04602645053 0.000612
+0.03023964579 -0.04728630978 -0.00796
+0.2659688415 -0.2254301616 -0.284548
+0.2687918892 -0.2009589141 -0.293344
+0.2905051622 -0.2175799108 -0.407782
+0.08829057416 -0.07029955959 -0.001248
+0.08984784404 -0.06798368732 0.000614
+0.08832271543 -0.06668212377 0.00062
+0.3442082845 0.2413451227 -0.039214
+0.3540285128 0.2547225585 -0.06279
+0.3364703427 0.2570918161 -0.03938
+0.1937526149 -0.3717867038 0.00062
+0.2043245471 -0.3702972744 -0.005592
+0.1980686551 -0.3847077323 0.00062
+0.09328284066 -0.07078631366 -0.001342
+0.09316693958 -0.07273624488 -0.00138
+0.09485099753 -0.07161767521 0.000614
+0.260998079 -0.5080118992 -0.006854
+0.255514363 -0.5010978076 -0.007158
+0.1827153458 -0.181892164 -0.010858
+0.1739728481 -0.1652276782 0.00062
+0.1757064469 -0.2233032865 0.00062
+0.1075600127 0.01620032563 -0.03774
+0.1105661177 0.02575416928 -0.043368
+0.09964145626 0.02602289887 -0.03969
+0.3220836357 0.1667767584 -0.005364
+0.3294947064 0.1717565654 -0.011376
+0.3217315754 0.1744842903 -0.007194
+-0.1919074371 -0.2672371458 0.000618
+-0.1836281678 -0.2782053625 0.000414
+0.2648812233 -0.6995837462 -0.015244
+0.298088337 -0.672935726 -0.00825
+0.2882419881 -0.6777529442 -0.007136
+0.2447265498 -0.03205550768 -0.12865
+0.2572014691 -0.02255721941 -0.03552
+0.2428090245 -0.01576509296 -0.020998
+-0.002422516009 -0.08625964335 0.000596
+-0.003486941202 -0.08396006123 0.000604
+0.0003777505778 -0.08592786423 0.000618
+0.2910852524 0.5372099745 -0.032292
+0.2773278082 0.5294899615 -0.023736
+0.2887899868 0.5214686464 -0.030728
+0.02123992521 -0.02714648289 -0.00533
+0.01708822226 -0.02822475676 0.000616
+0.02006015968 -0.03097866538 -0.007396
+-0.09431041716 0.1546452062 -0.00938
+-0.09431364572 0.1461313171 -0.011344
+-0.07480458859 0.1536635746 -0.013758
+-0.4644183059 0.5246302828 -0.19071
+-0.4234962796 0.5640493747 -0.023778
+-0.4287547321 0.5499668217 -0.037268
+-0.01509593028 0.8447397508 -0.014494
+-0.01819436609 0.8361366166 -0.01077
+-0.02334804947 0.8429831535 -0.014368
+-0.2062007472 -0.584948301 -0.043278
+-0.2177627657 -0.5780897536 -0.041612
+-0.2171312717 -0.5898651251 -0.047174
+0.3431883363 -0.4398015141 -0.097538
+0.3298862989 -0.456502399 -0.024892
+0.3497717578 -0.4607127385 -0.072712
+-0.3736290453 0.4526383366 -0.024104
+-0.3811021764 0.4634613708 -0.02619
+0.04539686769 -0.02872051783 -0.002238
+0.04187960262 -0.0284501614 0.00062
+0.03953872064 -0.03299010996 0.000616
+-0.3953181212 -0.2715760677 -0.100922
+-0.3520207198 -0.2208520737 -0.06554
+-0.3694276079 -0.1999510243 -0.073486
+0.06395186852 -0.05820248098 -0.001194
+0.0627072106 -0.06089713629 0.000618
+0.06589006202 -0.06260574607 0.00062
+-0.3844666393 0.1653849931 -0.02775
+-0.3414495203 0.1712580589 -0.024622
+-0.362966501 0.2878540628 -0.026662
+0.3305222689 -0.01981262947 -0.342776
+0.3256283599 -0.005591459036 -0.23774
+0.3388196842 -0.008140447793 -0.41079
+0.3977434787 -0.5153924445 -0.019196
+0.4158924963 -0.5269425228 -0.022512
+0.3933375487 -0.551869295 -0.018214
+-0.1248252274 -0.5850743501 -0.003856
+-0.11480161 -0.5824466145 0.00062
+-0.1209223058 -0.5780860426 -0.001916
+0.3227213742 0.6366525841 -0.019492
+0.3148410749 -0.5184493692 -0.016744
+0.2988005673 -0.5155903701 -0.017248
+-0.02607811506 -0.1445112695 0.00062
+-0.02764216597 -0.1338804454 9.2e-05
+-0.02929351905 -0.1422904109 0.00061
+-0.2609663965 -0.1915439707 -0.01938
+-0.2479127436 -0.183358594 -0.005742
+-0.2461070087 -0.1956814712 -0.011166
+-0.1376550821 0.1864485429 -0.005578
+-0.1228149322 0.1724610396 -0.006486
+-0.1193299838 0.1827021088 -0.003752
+0.2872068973 0.4862145772 -0.02852
+0.2758276286 0.4874434916 -0.017854
+0.2798363474 0.4770449206 -0.01806
+0.1023893328 -0.05215748885 0.000618
+0.1019801695 -0.04538482636 0.00062
+0.0991526836 -0.04592006301 0.00062
+0.3147804522 0.109915853 0.00062
+0.3238092791 0.1029510555 -0.009002
+0.3266001047 0.1131106068 -0.017336
+-0.1541153931 0.0756737876 -0.016124
+-0.143555419 0.07058951978 -0.015322
+-0.1553828446 0.06266444627 -0.016624
+-0.1278306045 -0.576549523 -0.004286
+-0.120387251 -0.5695553523 0.000616
+-0.241856238 -0.1535309579 -0.00938
+-0.2347010738 -0.1460285421 -0.007358
+-0.2446613282 -0.145162178 -0.00938
+0.1845606056 -0.02827233355 -0.043836
+0.1936439737 -0.02326046965 -0.017892
+0.1862189863 -0.01950639753 -0.01345
+-0.03529689008 0.0275811001 -0.014514
+-0.05173789372 0.02661055032 -0.015022
+-0.0427038012 0.01430042111 -0.013018
+-0.1419045786 0.1279003659 -0.018686
+-0.1130631033 0.1360717979 -0.015342
+-0.1201537509 0.1463845321 -0.012866
+0.3322497233 0.05380309289 -0.281704
+0.3249612211 0.05460371799 -0.213306
+0.328820452 0.06045410413 -0.244776
+-0.1743955771 -0.6440896544 -0.044422
+-0.178188564 -0.6558091318 -0.054068
+-0.167642144 -0.6576410543 -0.044696
+0.02596969729 -0.02335268519 -0.004024
+0.0231203777 -0.02414805131 -0.007558
+0.1193395416 0.06059585625 -0.025524
+0.1120500259 0.05752104424 -0.026298
+0.1205796582 0.0678336821 -0.023506
+0.07078712821 -0.009795756068 0.00062
+0.0675267357 -0.009824713944 0.000608
+0.06980602339 -0.01177040179 0.00062
+-0.002001234796 0.8545890182 -0.015816
+-0.006442839288 0.861118525 -0.019366
+-0.01088128045 0.8542112392 -0.018424
+0.09687172989 -0.04030312266 -0.002072
+0.09880430843 -0.03869254471 0.00062
+0.09716212465 -0.03881776739 -0.003786
+-0.1745785091 0.1512724983 -0.01427
+-0.1137462912 0.2228197395 -0.002134
+-0.1043153922 0.2219450005 -0.001882
+-0.1060870884 0.2299740486 0.00059
+-0.1489685626 -0.5069025672 0.000618
+-0.1495069859 -0.5008331002 0.000618
+-0.156895883 -0.5049849843 -0.004644
+-0.0156993152 -0.1106081986 0.000618
+0.03523230375 -0.1030076341 0.00062
+0.07851905244 -0.004626554134 -0.009854
+0.08774871988 -0.005730186181 -0.019558
+0.08511773787 0.001903712665 -0.019744
+0.110346106 -0.04023803235 -0.019374
+0.1040725719 -0.03846684081 -0.013572
+-0.1787777589 -0.5465040206 -0.025286
+-0.1971083566 -0.5129796136 -0.02788
+-0.1686224142 -0.5305866788 -0.015472
+0.06715819236 -0.06673032767 -0.004244
+-0.1873884886 0.1971218555 -0.00723
+-0.1802501493 0.2035853371 -0.002392
+-0.1865872507 0.208991712 0.000618
+0.3105707225 0.4549165468 -0.054942
+0.2985380714 0.4448349028 -0.02073
+0.3111752911 0.4369821023 -0.037188
+-0.08563555339 -0.07515227139 -0.00844
+-0.1007492743 -0.08396059006 -0.008398
+-0.09388380463 -0.09173730433 -0.008086
+0.2471297023 -0.2102735721 -0.174978
+0.2442654499 -0.2318352907 -0.216446
+0.3021453275 -0.5284990281 -0.01321
+0.3143836973 -0.5326344727 -0.0148
+0.02337741174 -0.08453071801 0.00062
+0.0222076281 -0.08522674734 0.00062
+0.02358011829 -0.08581253795 0.00062
+0.2723604818 -0.6054729975 0.00062
+0.2745214995 -0.6062503032 0.00062
+0.2628118103 -0.6072509136 0.00062
+0.3183711498 0.05639381249 -0.089584
+0.312090214 0.05115086155 -0.025494
+0.3199121583 0.04890224661 -0.058386
+-0.4667980696 -0.2760166886 -0.128588
+-0.4998930048 -0.2303984753 -0.144978
+-0.5021710144 -0.2667768555 -0.142842
+-0.1763597212 -0.4714965741 -0.00971
+-0.1644185015 -0.4706743028 0.00062
+-0.1746110458 -0.461485853 -0.005256
+0.4202246517 -0.304080219 -0.109692
+0.4415307691 -0.299982319 -0.060168
+0.4364602257 -0.3181621906 -0.075672
+0.1060230516 0.08789865507 -0.02291
+0.3270509491 0.1401445638 -0.009816
+0.3286066275 0.1481313856 -0.010046
+0.3216656291 0.1449957954 -0.003482
+0.08194821888 0.97453597 0.0003
+0.08867533811 0.9953532767 0.00062
+0.07937794345 0.9836710083 -0.008736
+-0.1191289945 -0.7234323799 -0.003082
+-0.1096189765 -0.7224828041 -0.001614
+-0.1118864818 -0.7144008312 -0.002968
+0.3853009507 0.09510649685 -0.334152
+0.3706198327 0.09824785526 -0.22303
+0.3816041347 0.1088397169 -0.280384
+0.5410193938 -0.2210339097 -0.05884
+0.5620702559 -0.2222715094 -0.087846
+-0.00723249376 -0.05424091504 -0.002154
+-0.009000096628 -0.05997631508 -0.001686
+-0.006068635654 -0.05901309845 -0.001024
+0.7154267648 -0.1990617063 -0.046574
+0.6838210419 -0.1717917744 -0.051672
+0.6889768999 -0.1945376185 -0.058054
+0.3045076746 -0.3331264619 -0.312472
+0.2738920287 -0.2955153131 -0.427588
+0.3138458263 -0.3072926502 -0.329954
+-0.4316224251 -0.2248945473 -0.119638
+-0.4506010745 -0.166294283 -0.12978
+-0.01513539502 -0.05009908952 -0.00565
+-0.02005210583 -0.05602508549 -0.007728
+0.06064593655 0.2091238446 -0.011404
+0.05759590139 0.2203742749 -0.00896
+0.04645966436 0.2218766996 -0.008078
+-0.05368823617 0.8188565259 -0.008856
+-0.04292233317 0.8259758564 -0.006848
+-0.06028299731 0.839739211 -0.018568
+-0.05078892328 -0.003144185529 -0.011518
+-0.05726873324 -0.01800737398 -0.010774
+-0.06006855703 -0.0005431806371 -0.012426
+-0.1803214571 -0.3695524175 -0.008508
+-0.1659750408 -0.3837631589 -0.005208
+0.4272732463 -0.2772253167 -0.122962
+0.3999169968 -0.2861015909 -0.155952
+-0.4485273716 0.4377549818 -0.205464
+-0.449597978 0.4042412745 -0.201636
+-0.4021600537 0.4391595879 -0.041306
+0.2511573568 -0.6730438135 0.00062
+0.06748829059 -0.06372969501 -0.005338
+0.06833183789 -0.06212475689 0.000612
+-0.1344533113 -0.5511361467 -0.00346
+-0.1426601956 -0.5466739206 -0.005828
+-0.1443620667 -0.5556538913 -0.00736
+0.2359181278 0.01323680674 -0.003424
+0.2448150744 0.01132704726 -0.004058
+-0.2984494931 -0.05438519771 -0.03458
+-0.2804853057 -0.03241626076 -0.029528
+-0.3012695169 -0.0136351798 -0.02988
+-0.02824055135 -0.08699406551 -0.007406
+-0.02294465911 -0.09193856098 -0.004316
+-0.01634340976 -0.08698453212 0.000618
+0.292935424 -0.6475656192 0.000618
+0.2924764492 -0.6499862158 -0.000966
+0.2962155368 -0.6501338594 -0.00317
+0.3867149784 0.554530614 -0.269012
+0.4286695757 0.5598613973 -0.260088
+0.4027298078 0.5920966132 -0.251188
+0.3074588147 0.0207996776 -0.03374
+0.301198086 0.02481777996 -0.005408
+0.01717227366 -0.0421947287 0.00062
+0.0155534683 -0.04785123644 0.00062
+0.0203308715 -0.04621317403 -0.008266
+0.1190121577 -0.09583045973 -0.005006
+0.1101800273 -0.0899540252 -0.00436
+0.1101679752 -0.1006203711 -0.003392
+-0.3998119499 -0.3465064037 -0.097858
+-0.3947819418 -0.3737180202 -0.085306
+-0.4488130565 -0.3756366797 -0.133032
+-0.05590586085 0.2215505716 -0.00346
+-0.06150516758 0.2119512676 -0.00338
+-0.05056172776 0.2100030553 -0.005168
+-0.2594601469 0.1638503792 -0.021788
+-0.2468930814 0.1095823763 -0.02137
+-0.2846097697 0.1334152537 -0.02393
+-0.1562280163 -0.7365935425 -0.01656
+-0.1589866133 -0.7255750682 -0.015124
+-0.1721245876 -0.723576124 -0.023288
+0.3809165755 0.3596040034 -0.203068
+0.3676376924 0.3779827485 -0.231814
+0.3574678281 0.3579886936 -0.147548
+-0.2975791369 0.001426789165 -0.026276
+-0.2928506949 0.02133136825 -0.02335
+-0.3117482826 0.01310024606 -0.030562
+0.4090671576 0.1774878273 -0.312518
+0.4008818271 0.1587109482 -0.264322
+-0.3582961275 -0.09371675015 -0.065012
+-0.3652643822 -0.06919541409 -0.05615
+-0.3839188075 -0.08083953021 -0.061738
+0.05486603563 -0.07321523999 0.00062
+0.05439421645 -0.07082718506 -0.001058
+0.05248140358 -0.07246236089 -0.001626
+0.2930315947 0.459900657 -0.023412
+-0.2203066566 0.3822306314 -0.004762
+-0.2248800951 0.3926303331 -0.005654
+-0.2309691763 0.383645725 -0.006818
+0.2900692395 -0.6476917626 0.00061
+0.2883848841 -0.6489403566 0.00062
+0.2893196932 -0.6465781113 0.00062
+-0.1061983101 0.804791548 -0.00452
+-0.09993129213 0.795201725 0.000116
+0.2665717955 0.7828468149 -0.00725
+0.2565515615 0.7816450838 -0.005272
+0.2621979084 0.7717049149 -0.007542
+0.356424314 -0.4197173343 -0.140622
+0.3685327153 -0.446007352 -0.121924
+0.1552858459 0.03440744243 0.000614
+0.1495836252 0.02548188061 0.000318
+0.1699399804 0.01712589522 0.00062
+0.2748931653 -0.5933281727 0.00062
+0.2736912476 -0.6025681283 0.000618
+0.2757895097 -0.605744704 0.00062
+0.301286572 0.5831144846 -0.029072
+0.3169779939 0.5774166624 -0.030842
+0.3160580781 0.5929247709 -0.026358
+0.6004165288 0.1067984261 -0.592786
+0.6212599737 0.13092515 -0.560072
+0.6250119441 0.06013812735 -0.522738
+0.3184895063 0.3291985681 -0.019594
+0.3324668868 0.3371803763 -0.032708
+0.3152309382 0.3453803859 -0.017204
+-0.225323896 -0.1157760883 -0.007736
+-0.2200440591 -0.120310569 0.000618
+-0.2170438284 -0.09919490919 0.00062
+-0.1550053452 -0.5383432693 -0.009434
+-0.1491834992 -0.5297347384 -0.00449
+-0.1462107024 -0.5389988482 -0.005192
+0.3869177022 0.08078878423 -0.40316
+0.3771408294 0.08821689439 -0.250398
+0.1332562481 0.141522665 0.000618
+0.1356050083 0.1309062909 0.000404
+0.1212548163 0.1375026406 -0.008258
+0.2234271811 -0.2388009871 -0.090116
+0.2123413125 -0.2242687338 -0.01938
+0.2092924532 -0.2360650104 -0.020414
+0.2624110328 0.4868181526 0.00062
+0.2609561475 0.4945072253 -0.003404
+0.2484533559 0.506861841 0.00062
+0.2659605563 0.5672752187 -0.019426
+0.2655120184 0.579892561 -0.018462
+0.2552998891 0.573136887 -0.014614
+0.09440279382 -0.0501712119 -0.003212
+0.09548948329 -0.04938019451 0.00061
+0.09582837489 -0.05083307831 0.00062
+0.2035738962 -0.05053920407 -0.0474
+0.2174034281 -0.04633860388 -0.108582
+0.2138337473 -0.06036065804 -0.07271
+-0.1652135932 -0.06536206416 0.00062
+-0.1695208173 -0.0655478208 0.00062
+-0.1699378402 -0.0676627754 0.00062
+0.0961372609 -0.069239811 0.000618
+-0.001020045443 -0.01190545354 -0.00538
+0.004369310759 -0.004944686773 -0.00138
+-0.003744239611 -0.006826232036 -0.003352
+0.1923547047 -0.3188297373 -0.025956
+0.1943765925 -0.3105167624 0.000616
+0.2035318895 -0.3165073813 -0.041348
+-0.2240350772 -0.3304844286 -0.022494
+-0.2056142583 -0.3346294071 -0.017274
+0.1299452383 -0.08337709115 -0.01059
+0.137885496 -0.08925032113 -0.011044
+-0.3172499358 0.6064522932 0.000618
+-0.3182135605 0.5912810411 0.000618
+-0.3137761583 0.5828588657 0.00062
+0.06016395441 -0.0633478981 0.00062
+0.06019385371 -0.06103304871 -0.001102
+0.05819442233 -0.06126014025 -0.001304
+0.06888750464 -0.0004211601966 -0.011944
+0.07192623539 -0.007747622382 0.00062
+0.3043049579 0.4704259534 -0.047086
+0.2909641863 0.4744661168 -0.028286
+0.3000463763 0.4847664812 -0.05091
+-0.3425464787 -0.04611336334 -0.051866
+-0.3513475413 -0.02847630606 -0.050466
+-0.3710269945 -0.03534050481 -0.053344
+-0.0656526206 0.8163762272 -0.010192
+-0.07366889784 0.824526382 -0.022628
+-0.07576813396 0.8135365367 -0.00914
+0.1195281109 0.08635584961 -0.016724
+0.1243669089 0.08949968572 0.000614
+0.08726457292 -0.05809996673 0.000618
+0.08871995457 -0.05827318685 -0.000544
+0.08602069507 -0.05948696964 -0.002134
+0.1771274724 -0.1022510531 -0.01891
+0.1709602644 -0.09065435098 -0.015962
+0.1852118162 -0.09086270852 -0.02144
+-0.1664732989 -0.4075764123 -0.002226
+0.388000165 -0.5684656305 -0.017636
+0.4064488564 -0.5651304289 -0.019916
+-0.002157106704 0.01045288981 -0.012754
+-0.004109672481 0.0009582408434 -0.00523
+-0.009244920261 0.00865251573 -0.00608
+0.3006881885 -0.623295222 0.000618
+0.321793692 -0.6160032783 0.000616
+0.3223215217 -0.6096992075 0.00062
+0.3345188395 0.03080358538 -0.132856
+0.3314849187 0.02209890826 -0.154354
+0.3398440222 0.02393992378 -0.26034
+0.04158242079 -0.05922377714 -0.00338
+0.04273958709 -0.05981823424 -0.001426
+0.04258273832 -0.05858678716 -0.001742
+0.318939546 0.3590398895 -0.032182
+0.32588106 0.3650316294 -0.064256
+0.3152580027 0.371685457 -0.077964
+0.2907160614 0.7188331636 0.000618
+0.289608786 0.7168661433 0.00062
+0.2966542596 0.7099532913 0.00062
+-0.2464395426 -0.209647045 -0.01324
+0.4210364743 -0.4039606945 -0.113792
+0.3975585298 -0.3688536759 -0.11071
+0.3688118096 -0.3980752774 -0.117562
+0.3128283734 0.1257270857 0.00062
+0.3137200585 0.09680665004 0.00062
+-0.007837146449 -0.00484021062 0.00062
+-0.01433332136 -0.006818698052 0.000604
+-0.242470196 -0.07734949398 -0.017202
+-0.2998895671 -0.4422923434 -0.042472
+-0.2916722836 -0.4576455407 -0.046118
+-0.260847092 -0.4394921776 -0.031152
+0.1410905493 -0.0232262892 -0.029564
+0.1328815818 -0.0214612908 -0.05203
+0.1331527059 -0.0322884313 -0.043966
+-0.2944964942 -0.42503806 -0.03624
+-0.3093215321 -0.4118078029 -0.038806
+-0.3156223794 -0.4323349543 -0.051272
+-0.002625626018 -0.08003244679 -0.001174
+-2.344747215e-05 -0.08024689135 0.00062
+0.3036176978 0.5272300308 -0.047228
+0.03158373906 -0.04705661043 -0.005346
+0.03234222642 -0.04612965427 -0.003746
+0.09224452819 -0.06797754815 0.00062
+0.08941662598 -0.07138467894 -0.001268
+0.4097890662 -0.422606158 -0.111236
+0.4361106668 -0.4205757065 -0.11101
+0.2571286517 0.003372028625 0.000616
+0.2823508566 -0.001171420679 0.000618
+0.7722735964 -0.2582373426 -0.096732
+0.8031705055 -0.2377345118 -0.111104
+0.7721594152 -0.2177035398 -0.093102
+-0.145414906 0.7702091951 -0.003008
+-0.1458919322 0.7730658702 0.00042
+-0.1439385292 0.7709051267 0.00042
+0.1251065966 0.1621959317 0.000618
+0.1189050543 0.1740776992 0.000582
+0.1115704657 0.1696648894 -0.004482
+-0.3304873744 0.005707830004 -0.040274
+-0.3321984863 -0.01451348531 -0.044194
+-0.2368650122 -0.1862371353 -0.006362
+-0.2322902748 -0.1922391443 0.000618
+0.5034308697 -0.259712638 -0.023078
+0.5023341746 -0.2733205491 -0.020436
+0.5205943058 -0.2666613169 -0.015576
+0.4043337827 -0.259330731 -0.17646
+0.2702920534 0.7073667938 0.00062
+0.2740123986 0.7124635774 0.00062
+0.2732610857 0.7083309536 -0.001402
+0.02046231741 -0.04192453638 -0.008562
+0.01723187408 -0.03912704278 0.00062
+-0.434726738 -0.113944934 -0.11477
+-0.4872194686 -0.08754094491 -0.135026
+0.09680906956 -0.04206142469 -0.00321
+0.09644010584 -0.04135690883 -0.003152
+0.3005088065 0.4326405501 -0.019728
+0.2942019626 0.4241144218 -0.011376
+0.2907455335 0.4365323405 -0.010872
+0.3863397504 -0.4677181703 -0.047434
+0.4133752705 -0.469023008 -0.098808
+0.3970603363 -0.4460059161 -0.117632
+0.03069216123 0.82736869 0.00062
+0.0326921152 0.8253815301 0.00062
+0.03641609082 0.8280335706 0.00062
+0.03743318487 -0.1040569101 0.000618
+0.03971665905 -0.1041649362 0.00062
+-0.5362077433 -0.2976497137 -0.148628
+0.03239545017 -0.0644785536 -0.003736
+0.03366781584 -0.06599141537 0.000612
+0.03561040851 -0.06464811761 0.00062
+0.3217421778 -0.3537231921 -0.241842
+0.2938251288 -0.362113525 -0.297542
+0.3155467603 -0.3834090797 -0.224852
+-0.09497395158 -0.1438128994 0.00062
+-0.09072473896 -0.1363634606 -0.001926
+-0.09799106624 -0.1317685824 0.00062
+0.05700992693 -0.05984749516 -0.000544
+0.05549427041 -0.06352476328 0.00062
+0.04712628089 -0.05799162694 0.00062
+0.05120986437 -0.07016564969 0.000614
+0.05586713839 -0.07701525432 0.00062
+0.05699472489 -0.07679341427 -0.001706
+0.05667997621 -0.07537550117 0.00062
+0.2489047009 -0.5992988844 0.000618
+0.2507773863 -0.5997367518 0.00062
+0.247528515 -0.6016605711 0.00062
+0.2977447203 -0.6472307901 0.000616
+0.3023099486 -0.6471077193 -0.001862
+-0.09894778318 0.181528481 -0.00549
+-0.1011907004 0.1946366972 -0.00338
+-0.1112143454 0.1882104846 -0.005428
+0.06247080009 0.2292089602 -0.004316
+0.09218798124 0.2143364195 0.000616
+0.06920779888 0.2190833677 -0.007534
+-0.180344137 -0.820817832 -0.035648
+-0.1914679601 -0.8267935254 -0.03938
+-0.192196984 -0.8094398897 -0.054378
+-0.2742373344 0.3850426217 -0.013028
+-0.2617479006 0.36629002 -0.01237
+-0.2714845457 0.3603214128 -0.01416
+0.2043532671 -0.55864209 -0.002396
+0.1977307978 -0.5412917361 -0.002222
+0.1868914631 -0.534713956 0.00062
+-0.2440764213 0.4610818742 0.000616
+-0.2603219591 0.5029450629 0.00062
+-0.2324941177 0.4479039458 0.000616
+-0.3049387697 -0.3926146067 -0.033914
+-0.3246312756 -0.3982969949 -0.052236
+0.08259474207 -0.0195004834 0.000616
+0.0763915974 -0.01966872968 -0.00138
+0.07579257511 -0.01264996143 -0.003196
+0.09226364253 -0.08261450693 -0.002196
+0.09135109324 -0.08595672083 0.00062
+0.09420257337 -0.08571300559 -0.003568
+-0.2285351991 0.3750154245 -0.006078
+-0.2394132969 0.3840142084 -0.008482
+0.08824926895 -0.03991614514 0.000592
+0.2878615624 -0.6581689267 -0.00318
+0.2889578795 -0.6525544154 -0.001256
+0.2811947402 -0.6509536666 0.000618
+0.1800790539 -0.3330998919 0.00062
+0.1898069908 -0.3498992968 0.00062
+0.2686793227 -0.4433213939 -0.02046
+0.4970930687 0.4102555644 -0.465018
+0.4606674663 0.4437945419 -0.42951
+0.4203501809 0.380818865 -0.381328
+0.01462589759 0.01408112757 -0.012248
+0.001494883225 0.02898340346 -0.017144
+0.2928233109 0.3250646642 0.00062
+0.2960280487 0.3114559162 -0.005
+0.301217873 0.3196391499 -0.007852
+0.1152791548 0.01979453565 -0.050378
+0.1172840129 0.01289078471 -0.05979
+0.8325152606 0.08363301031 -0.138142
+0.8583212689 0.06577875833 -0.080042
+0.8235151764 0.05766014764 -0.087336
+0.05580334783 -0.01231780055 0.00062
+0.05764901475 -0.01216556537 0.00062
+0.05628465037 -0.006592196392 0.00062
+-0.302674817 0.4264514895 -0.016274
+-0.3175026379 0.3960263877 -0.0178
+0.09041261237 -0.05376254361 0.00062
+0.08902834671 -0.05367425261 -0.000614
+0.08891181725 -0.05484236812 0.000616
+0.3958616435 0.1040699116 -0.378494
+0.4067536156 0.1134219589 -0.400942
+0.2663342794 0.5212863123 -0.015558
+0.2583898003 0.51280025 -0.00918
+0.2699308273 0.5072166561 -0.0138
+-0.1308229055 -0.7462343033 -0.004814
+-0.1142288938 -0.7326992133 -0.001408
+-0.1253645201 -0.7345340786 -0.0036
+0.05854996148 -0.0752555662 0.000616
+0.05889180019 -0.07253271647 0.00062
+0.04633061484 -0.0773987335 0.00062
+0.04530503622 -0.07982822229 -0.000836
+0.04724644198 -0.07953060455 0.000618
+-0.02536439677 -0.01232826851 0.00062
+-0.02153539566 -0.01084626579 0.00062
+-0.02558088123 -0.01338176806 0.000614
+0.11617437 0.07318293476 -0.025066
+0.1216076143 0.07374356587 -0.023894
+0.1199407808 0.07921783699 -0.02184
+-0.3472552844 -0.2639256431 -0.05541
+-0.3452573521 -0.2425005113 -0.05984
+-0.6193357905 0.2183028596 -0.291788
+-0.6961429849 0.2774428478 -0.339976
+-0.6617121686 0.1594124699 -0.302622
+0.3113989983 -0.6386945267 0.000618
+0.3096202609 -0.6346573754 0.00062
+0.03141787298 -0.07479330757 -0.00322
+0.03217337632 -0.07334440962 0.0006
+0.03050150302 -0.07292267529 -0.004522
+0.2348332014 -0.4480475322 -0.010232
+0.2283791806 -0.4645908369 -0.009444
+0.2375140158 -0.4662556006 -0.010826
+-0.1422245006 0.7763902621 0.00062
+-0.1400381214 0.7747843797 -0.002436
+-0.1430778333 0.7749144034 0.00062
+0.2417298111 -0.06751392402 -0.078088
+0.2551575918 -0.07939232549 -0.083104
+0.2591626402 -0.06095260049 -0.242492
+0.01452770737 -0.06177970296 0.000618
+0.01531091427 -0.0561836836 -0.002176
+0.01110848317 -0.05902607015 -0.005168
+0.332530212 -0.4203200496 -0.12944
+-0.134400782 -0.6034660488 -0.015808
+-0.1236148067 -0.6061095744 -0.006596
+-0.1298507402 -0.5947479558 -0.008038
+0.06464617348 -0.06556092172 0.00062
+0.06674515035 -0.06493196286 0.00062
+-0.06131167934 0.2010038588 -0.004742
+-0.212906346 0.3744092985 -0.003266
+-0.2098957551 0.3846407595 -0.001968
+0.04353513216 -0.08970682743 -0.000902
+0.04314701581 -0.08820439687 0.00061
+0.04553397195 -0.08999843974 -0.000958
+0.3282391661 0.3201113535 -0.031464
+0.3476463047 0.3044922239 -0.06413
+0.3239857252 0.3058358546 -0.03295
+0.1836219281 -0.2977929835 0.00062
+0.1845372027 -0.2699874534 0.00062
+0.1853533095 -0.285281953 0.00062
+-0.06720207509 0.1920421991 -0.008096
+-0.05646766759 0.1887474787 -0.008818
+-0.09468405692 0.7936975216 0.00013
+-0.08621557384 0.799755735 -0.003482
+-0.09536759419 0.8044836107 -0.004428
+-0.4063984792 -0.0964311205 -0.082
+-0.4015697639 -0.1238393823 -0.090282
+0.2508310314 -0.5970793186 -0.000978
+-0.2219331869 0.3697937124 -0.004692
+0.03287005321 -0.04754261107 -0.00938
+-0.2060927855 -0.4888084462 -0.028684
+-0.2090053355 -0.5039540562 -0.031176
+0.2405570755 -0.1264162064 -0.147622
+0.2281324882 -0.1420999264 -0.035984
+0.2470436163 -0.1462191767 -0.1882
+-0.01816927342 0.2341399899 -0.00341
+-0.007448978964 0.2299939889 -0.0049
+-0.007716302104 0.2410758531 -0.00255
+0.1378580524 0.05955984228 -0.01053
+0.1406294913 0.07129818253 -0.0055
+0.1336261346 0.06602968316 -0.011402
+0.2735105933 0.693258784 -0.00464
+0.2762077339 0.6993928439 -0.003568
+0.3729499379 0.6423330184 -0.149466
+0.3522123258 0.6462479195 -0.051026
+0.3609922837 0.6613733752 -0.06113
+-0.1789985748 -0.6798138041 -0.062722
+-0.1722207506 -0.6672569849 -0.041762
+-0.1865802852 -0.6629518291 -0.058456
+-0.2694682989 -0.08513294692 -0.025658
+-0.30393059 -0.08286301129 -0.040352
+-0.3008634702 -0.1019107893 -0.037502
+-0.08769317285 0.2169663073 -0.002668
+-0.07801081915 0.2160310119 -0.00338
+-0.07957975349 0.2291858783 0.000618
+0.2533813525 -0.5330388944 -0.004756
+0.2586877536 -0.5252755495 -0.004604
+0.2582902839 -0.5419973165 -0.004398
+0.1082931317 -0.04824867064 -0.01873
+-0.5684676553 0.04679879264 -0.191306
+-0.5960026757 0.02038080307 -0.180032
+-0.5567562881 0.006149199505 -0.164204
+-0.01552549099 -0.04467379791 -0.003758
+-0.01070076041 -0.04673481915 0.000612
+0.3281979216 0.1620799976 -0.009264
+0.3333958865 0.1555707199 -0.015508
+0.3363501288 0.1642395323 -0.02034
+-0.06890094941 0.219261566 -0.00338
+0.02638015574 0.2125001474 -0.00938
+0.01925383967 0.2238612376 -0.007274
+0.01447832386 0.2127496626 -0.009188
+0.3391079143 0.4111973452 -0.163944
+0.3212196146 0.4073024334 -0.040554
+0.3248286525 0.4253258367 -0.06268
+-0.1317223511 -0.6449508694 -0.021144
+-0.1235215814 -0.6591588941 -0.017358
+0.5297157062 -0.4045690862 -0.085392
+0.528861401 -0.3816491662 -0.07345
+0.4864557651 -0.4020343949 -0.088152
+-0.01149446348 0.04371423454 -0.020274
+-0.001476586239 0.03912268118 -0.020618
+0.0008113041951 0.04957426249 -0.025382
+-0.3446034121 0.03743715808 -0.037802
+-0.3135384472 0.04058286433 -0.027112
+0.03521215226 -0.05085447115 -0.003478
+0.03549884182 -0.04962764098 -0.003982
+0.5149448121 -0.309639445 -0.024588
+0.5353200238 -0.306163242 -0.015614
+0.5240223942 -0.324366065 -0.019274
+0.0422739887 -0.086906968 0.00062
+0.0418194062 -0.0881897499 -0.000978
+-0.224161339 -0.03717334552 -0.016682
+-0.2514571075 -0.05137815281 -0.023078
+-0.2344419743 -0.02967371358 -0.019932
+0.3644802391 0.2108711185 -0.210906
+0.3602198176 0.1951597122 -0.206096
+-0.1598236038 -0.5156148777 -0.007478
+-0.1528447591 -0.5120007688 -0.003282
+0.04171045646 -0.008840266219 -0.002528
+0.1471137328 -0.03286020774 -0.036394
+0.1492592312 -0.02416204455 -0.021324
+0.03773465453 -0.07786662649 -0.00383
+0.03707803031 -0.07812893011 -0.004916
+0.038250161 -0.07900040878 -0.003846
+-0.1890712193 0.7620124088 0.00062
+-0.1701039631 0.761234158 0.00062
+-0.1724519298 0.7644432469 0.00062
+0.3635406201 -0.5612807092 -0.01641
+0.3748656159 -0.5549641976 -0.016126
+0.3674202007 -0.5431924049 -0.016028
+0.5489759772 -0.2386779263 -0.041262
+-0.1021733927 -0.1108398919 -0.00549
+-0.1090525288 -0.1155061916 0.00062
+-0.1114650413 -0.1093244709 -0.005368
+0.811150189 -0.1641530145 -0.079658
+0.7835202107 -0.1720030146 -0.074468
+0.7833711936 -0.1935825305 -0.094358
+0.3222808505 0.2807337991 -0.034286
+0.332943119 0.2931250598 -0.053334
+0.3121536548 0.3036219249 -0.019074
+0.01864400344 -0.0164520682 0.00062
+0.01529065861 -0.01796054368 0.00062
+-0.1199235598 -0.5932424649 -0.00338
+-0.1149352657 -0.5997811708 -0.002114
+-0.1107952345 -0.5906097421 0.000362
+0.0883719187 -0.07692160493 0.00062
+0.08995505133 -0.07698692629 -0.00122
+0.08992591407 -0.07851743536 0.00062
+-0.2990620255 -0.2901828386 -0.040264
+-0.3133893675 -0.3080393005 -0.047814
+-0.2931630812 -0.3069603011 -0.038618
+-0.3257115117 0.5879155279 -0.005696
+-0.3165683365 0.5845834795 0.000618
+-0.4382645915 0.05208541239 -0.06347
+-0.4534882967 0.03806347737 -0.051654
+-0.46053925 0.06499831491 -0.093252
+0.3967796993 -0.3148501174 -0.130264
+-0.3440779607 0.6115448291 -0.005
+-0.3478774208 0.622247994 -0.002288
+-0.3544856318 0.6147224179 -0.00573
+0.2094169241 -0.01086133759 0.00061
+0.2149656151 0.007684092271 0.00062
+0.2180626827 -0.00189780574 -0.074196
+0.265881798 0.6853160166 -0.005852
+0.2759946951 0.6832340908 -0.005828
+0.2246044556 0.5512548975 -0.004442
+0.2268111663 0.562674692 -0.006274
+0.02483171151 -0.02042288604 -0.005038
+0.02826640961 -0.02032595078 0.00061
+0.02816990294 -0.01889992311 0.00062
+-0.6072353625 -0.3752631959 -0.172894
+-0.2469181394 -0.8085686413 -0.174528
+-0.4463027444 -0.5486146355 -0.170806
+0.3302353154 -0.06184044989 -0.441556
+0.3343261833 -0.04110287367 -0.441044
+0.3386038581 -0.05268302258 -0.469998
+-0.2907834158 0.279416882 -0.024272
+-0.2785945074 0.2856574341 -0.022112
+-0.2745827373 0.2973053966 -0.02019
+0.0405471844 0.1066505066 -0.022996
+0.05818456371 0.1345280052 -0.022136
+0.04203694712 0.1530499602 -0.020434
+0.3638535146 -0.1877991295 -0.4232
+0.3848534922 -0.197870705 -0.321154
+0.3792536614 -0.1458057458 -0.491372
+0.04290007802 -0.05269451361 0.00062
+0.04419805814 -0.05659265307 0.000606
+0.04287017552 -0.05474941167 -0.001602
+0.2386503029 -0.2872269299 -0.203682
+0.2161133389 -0.1554008195 -0.030678
+0.2108967933 -0.1387387108 -0.024832
+-0.1253363236 -0.6351238261 -0.01563
+-0.1136946742 -0.6350457161 -0.005416
+-0.119358023 -0.646156435 -0.011574
+-0.1626362584 -0.07512238559 -0.002208
+0.3648579742 0.1303763974 -0.197466
+0.3674687967 0.1137010149 -0.297378
+0.7088641059 -0.03803496621 -0.075282
+0.7589193915 -0.0003011256956 -0.0716
+0.7360395598 -0.04963338816 -0.05943
+0.04357678073 -0.04722700789 -0.002738
+0.04250627568 -0.04595069603 -0.001388
+0.04198980527 -0.04768850599 -0.002686
+0.1349465476 0.09761034519 -0.00681
+0.1394429886 0.0913303939 0.00061
+0.1416790658 0.1026983815 0.000618
+-0.5576644931 -0.03289129926 -0.164238
+0.04309252534 -0.08032512825 0.00062
+0.04439404759 -0.08213277275 -0.001212
+-0.3473755646 0.01654381476 -0.042958
+0.7188002219 -0.2445153462 -0.084038
+0.6974929817 -0.2246075167 -0.079216
+0.6715981363 -0.2452716351 -0.07307
+0.01306700837 -0.07986148683 0.00062
+0.01349251517 -0.07828185198 -0.00131
+0.01189133016 -0.07794734439 0.00062
+0.2643091779 -0.6827754763 -0.003224
+0.2708785799 -0.6913101527 -0.040692
+0.2613647948 -0.6916317544 -0.006536
+-0.2628095452 0.1957491313 -0.021724
+-0.2576799203 0.2078328981 -0.018994
+-0.2716805372 0.2078183031 -0.022314
+-0.5439458796 0.07901676332 -0.159454
+-0.5475913844 0.1192068816 -0.172496
+-0.5740241979 0.1011048848 -0.19313
+0.2305991177 -0.4249575033 -0.009542
+0.2422412123 -0.4280628119 -0.012714
+0.2335840502 -0.433501203 -0.00964
+-0.1371212092 0.006730420262 -0.012828
+-0.1262224691 0.008329155563 -0.013056
+-0.1306577077 0.02667591803 -0.01409
+0.3403309204 -0.3009955946 -0.264022
+0.01931061721 0.2372389609 -0.003792
+0.02121206737 0.2526958526 0.00062
+0.02841689163 0.2417467173 -0.003054
+0.03542669535 -0.03751005333 -0.004652
+0.0344097252 -0.0386530301 -0.00538
+0.0361669992 -0.03970109951 -0.00461
+0.2327308571 -0.1049592587 -0.025434
+0.2111422798 -0.1065012303 -0.031686
+0.2210094913 -0.1236239844 -0.030804
+0.09387326589 -0.06600827362 0.000614
+0.09429686099 -0.05972110121 0.00062
+0.09294934964 -0.06359630274 0.00062
+0.004031847978 0.2106807951 -0.009028
+0.01045928061 0.2047540949 -0.009842
+-0.3313147148 0.5980234668 -0.005432
+-0.3221197705 0.5979548218 -0.003724
+-0.3885436193 0.0858036615 -0.034914
+-0.3513537714 0.08702547619 -0.029566
+-0.3820596479 0.1041313907 -0.030786
+0.2772265981 0.5170783407 -0.020296
+0.2939096699 0.4973591501 -0.03608
+0.2995799882 0.5112341299 -0.04526
+-0.006099319117 -0.02630351237 0.00062
+-0.002403372411 -0.02493541252 0.000564
+-0.004854293874 -0.0269974683 0.000618
+-0.1612985476 -0.004446627174 -0.013348
+-0.1769503101 0.009435385766 -0.01606
+-0.1515785864 0.009561096763 -0.014762
+-0.3424053753 0.1548557341 -0.025178
+-0.3840711603 0.134194961 -0.027864
+-0.1397941911 0.7770229781 0.00062
+0.3190261551 0.08807490857 -0.012776
+0.3272112064 0.08830142371 -0.028718
+0.3230152114 0.09459024156 -0.015258
+0.07449749957 -0.03418004179 0.00062
+0.07601673394 -0.032593303 0.00062
+0.07349993648 -0.02879196725 0.00062
+-0.1154831256 -0.1137061441 0.000614
+-0.1380176541 -0.1216462017 0.00062
+-0.1100377181 -0.1192770269 0.00062
+-0.1392946822 0.2188887115 -0.002334
+-0.1356977858 0.2295851842 0.000618
+-0.1303498466 0.2170137625 -0.00282
+0.294610832 0.6675433449 -0.007358
+0.3041323968 0.6695922834 -0.003
+0.298210002 0.6620180448 -0.007916
+0.2824814701 0.6347100925 -0.016988
+0.2717272044 0.6531458231 -0.01003
+0.2656410777 0.6452212168 -0.012584
+0.3135248078 0.01516515836 -0.099516
+0.3243040703 0.1277556223 -0.00987
+0.3244603529 0.1347977102 -0.010248
+-0.2618511247 0.2975091636 -0.015884
+-0.2521615898 0.2921655821 -0.006208
+-0.2681671982 0.2886024979 -0.019522
+0.2067734958 -0.4932082894 -0.003392
+0.2036408051 -0.50480149 -0.003372
+0.1985420025 -0.494626141 0.00062
+-0.002401712126 0.8371153307 -0.008152
+-0.005000510131 0.845566354 -0.012356
+-0.009659241977 0.83724082 -0.009554
+-0.02098292879 -0.03506830242 0.000586
+-0.01869117145 -0.03255446689 0.00062
+-0.01791840072 -0.03713240126 0.000616
+0.2309358988 -0.3765954315 -0.03938
+0.2490963256 -0.3838663002 -0.04476
+0.2482687369 -0.3626083378 -0.13343
+0.1438767713 0.08353381213 0.000594
+0.1482060394 0.07639823211 0.000618
+0.3382399143 0.1723671644 -0.023306
+0.1317762673 0.07411314756 -0.00722
+-0.1503799397 -0.7231118871 -0.010068
+0.3009206948 0.349289876 -0.007106
+0.2967425364 0.3406175427 0.00062
+0.304337764 0.340301429 -0.00619
+0.03220135155 -0.0438698424 -0.002332
+0.03570393418 -0.04411967854 -0.004572
+0.03402040381 -0.04106718904 0.00062
+0.320882893 0.007403910343 -0.205794
+0.313154252 -0.003153691575 -0.194836
+0.3537186821 0.3958047025 -0.23131
+0.3754882926 0.399063977 -0.254484
+0.6444859828 -0.3468642143 -0.08435
+0.672070344 -0.3585869941 -0.102382
+0.6159600344 -0.3944251716 -0.093352
+0.1196440113 0.1168010788 -0.012038
+0.1247182494 0.1068872641 -0.009726
+0.1310914976 0.1134914819 -0.006538
+0.2443501321 -0.5035418744 -0.006476
+0.2500614647 -0.4844589159 -0.008956
+0.2074728943 -0.357781313 -0.050036
+0.2171530923 -0.365650597 -0.034958
+-0.2674059668 -0.2601064796 -0.025648
+-0.2456578719 -0.2659218824 -0.022596
+-0.2356972325 -0.2387562947 -0.016988
+0.02500003868 -0.01616638713 -0.00938
+-0.03031570596 -0.006974068655 -0.01272
+-0.02731174396 -0.002934962046 0.00062
+-0.02769526773 -0.008774246288 0.000614
+0.2459508576 -0.0006242765287 -0.010962
+0.2556139892 -0.009021217519 -0.014862
+-0.1413544465 -0.9308351361 -0.003284
+-0.1543729941 -0.9189966478 -0.008452
+-0.1441693821 -0.9211671065 -0.004616
+0.2055109899 0.6367949504 -0.002624
+0.04341079783 -0.06140087875 0.000612
+0.0440107128 -0.06237630353 -0.00047
+-0.03480954499 0.1984819607 -0.00893
+-0.03849642317 0.1804594521 -0.013296
+-0.01076116323 0.1726374167 -0.016572
+0.01266484144 -0.05434667601 0.000618
+-0.2528688927 0.3008185284 -0.006416
+-0.2460379066 0.2996809761 0.000618
+0.2710896233 0.7239375464 0.00062
+0.2793687511 0.716852868 0.00062
+0.3834670669 0.2144801437 -0.238868
+0.3687709972 0.2292822711 -0.180886
+0.03942208827 -0.08872757849 0.00062
+0.04073448947 -0.08820312795 -0.001202
+0.04040403789 -0.08702954604 0.00062
+-0.1538995755 -0.6844751417 -0.018742
+-0.1491319839 -0.7011572617 -0.009284
+-0.1646605342 -0.6909211268 -0.036746
+-0.3063326259 -0.640808409 -0.168384
+-0.3270848534 -0.6673685951 -0.184122
+-0.2914766869 -0.6725753731 -0.179532
+0.1974594776 0.6457244303 0.00062
+0.2096264257 0.6630532075 0.00062
+0.2097843204 0.6459405025 -0.003068
+-0.02840084862 -0.01082047316 0.000606
+-0.03729565486 -0.01756383812 -0.011164
+-0.1190954532 -0.6718676762 -0.01075
+-0.131868994 -0.6716749747 -0.035862
+-0.1205276526 -0.6839461494 -0.009418
+0.06391668965 -0.07408628449 0.000604
+0.06174699654 -0.07358720496 -0.00299
+0.06278958183 -0.07613379696 0.000616
+0.08671568287 -0.0624089802 0.00062
+0.09049196873 -0.06614228715 0.00062
+0.7090061848 -0.1147586505 -0.05468
+0.7125335817 -0.1382264202 -0.054268
+0.6877003198 -0.129997084 -0.059586
+0.01192854284 0.1962684942 -0.011866
+0.002759939263 0.2004247627 -0.0112
+-0.2614893466 0.4539244047 -0.008878
+-0.2554514452 0.4455509436 -0.008614
+-0.2502035206 0.4564433582 -0.006188
+-0.4050059994 0.02941720003 -0.04873
+-0.4306743853 0.03291615135 -0.049738
+-0.4248547038 0.0108350601 -0.04999
+0.03961641953 -0.07462889674 0.00062
+0.0414487635 -0.07889248091 0.000608
+0.3067376801 -0.6446122411 -0.005058
+0.3028541095 -0.644292892 0.00062
+-0.04696321219 0.8402196648 -0.014532
+-0.04367241307 0.8542911359 -0.0196
+-0.05631363539 0.8523775617 -0.03427
+0.3227129854 -0.03892084041 -0.390742
+0.2360543632 0.6512834221 -0.005618
+0.2455145173 0.6551514562 -0.005716
+0.239796981 0.6599940731 -0.00476
+0.2920378238 -0.5475524304 -0.006718
+0.2937795102 -0.536394369 -0.009852
+0.2832149485 -0.5382325339 -0.006114
+-0.2316731922 0.3644025962 -0.006988
+-0.2413040114 0.3656538528 -0.009054
+0.274528836 0.7100882716 -0.000712
+0.08584762635 -0.04620228535 0.000606
+0.08270923684 -0.04506116403 -0.008342
+0.8004088478 0.08967151558 -0.173708
+0.7855039253 0.05065788919 -0.107772
+0.3540341426 0.1412637089 -0.169542
+0.3669002966 0.1476852347 -0.178868
+0.2722429995 -0.5974251783 -0.00108
+0.03636911683 -0.05223219933 0.00062
+0.03795435467 -0.05464246894 0.00062
+0.039484326 -0.05306777008 -0.0052
+-0.003031904695 -0.06235010215 0.00062
+-0.005548337428 -0.06302100282 0.000618
+0.06168777723 0.9429923737 -0.012432
+0.03547934561 0.9373397003 -0.040518
+-0.1906188179 -0.6311158635 -0.046148
+-0.1900857509 -0.6476138403 -0.05108
+-0.278316278 -0.6466197795 -0.156686
+-0.1205629701 0.08826900313 -0.01857
+-0.1183834719 0.07194840369 -0.016358
+-0.1063272008 0.08617969838 -0.01994
+-0.03944788488 -0.0886105441 -0.008192
+-0.03666064873 -0.0721187546 -0.009264
+-0.04520534748 -0.0675120583 -0.009544
+0.07195163262 -0.0755805388 0.00062
+0.06991167156 -0.07914637237 -0.001762
+0.06872674893 -0.07695132439 -0.004212
+0.3084048099 0.3329568845 -0.010278
+0.3024193864 0.3265903286 -0.006662
+0.3088833361 0.3227794862 -0.01265
+-0.04779836007 -0.1732917911 0.00062
+-0.05158286893 -0.1675842693 -0.00017
+-0.05408005831 -0.1731744969 0.000558
+-0.04235921568 0.00233702535 -0.00938
+-0.04250103812 -0.005102443879 -0.009614
+-0.03489668288 -0.002847052339 -0.010374
+-0.4811387979 0.200695573 -0.05968
+-0.4634103603 0.2169016075 -0.028748
+-0.2051409872 -0.03659637322 -0.014856
+-0.1828545178 -0.01349510924 -0.013292
+-0.1937865299 -0.01066495423 -0.012888
+0.8576434434 -0.08878621657 -0.070982
+0.8790340451 -0.1023631723 -0.081846
+0.8840188153 -0.07351322613 -0.072212
+-0.1209767883 -0.04986075246 -0.009212
+-0.1422311259 -0.04453194202 -0.009342
+-0.1348092578 -0.0318255336 -0.010406
+0.07550186783 -0.05893170436 0.00062
+0.07704192488 -0.06024957333 -0.001896
+-0.09783509863 -0.1008707658 -0.006184
+-0.08621892895 -0.09915259788 -0.007714
+0.3456035821 -0.01942576597 -0.453394
+0.405778787 0.2717223612 -0.312604
+0.4055180663 0.2472806686 -0.285094
+0.4214963122 0.2582172646 -0.328904
+0.2465938325 -0.5943978331 -0.002146
+0.2391172547 -0.5914314433 -0.002178
+0.2436713756 -0.5969494784 -0.001286
+0.2751338057 0.7044767665 -0.002608
+0.3095683764 0.1797506332 0.00062
+0.3190109402 0.5624539966 -0.061372
+0.3323607771 0.5723712283 -0.078142
+0.3317836806 0.5481837533 -0.094166
+-0.04762900554 -0.01239290963 -0.009526
+-0.03685717136 -0.009436695866 -0.010116
+0.1111874257 0.005763958849 -0.047494
+0.1148262368 -0.003625552436 -0.058198
+0.1208938347 0.004316190632 -0.05639
+0.2365533724 -0.08504248827 -0.01938
+0.03372327979 -0.05979285319 -0.002956
+0.03303728519 -0.05845447465 0.00062
+0.03466646504 -0.05856492806 0.00061
+-0.2517794038 0.2382804507 0.000618
+-0.2404309063 0.2232211542 0.000596
+-0.2555065757 0.2638845005 0.000618
+0.03793336244 -0.07679951777 -0.00217
+0.03661883416 -0.07628006704 0.00059
+0.02057136365 -0.02503999075 0.000614
+0.09609748697 -0.04618301607 -0.001978
+0.09499488879 -0.0474787334 0.00062
+0.09480070258 -0.04541353507 0.00062
+-0.05875177882 0.09011640845 -0.018848
+-0.04136928825 0.0976804386 -0.019448
+-0.05285214957 0.09922509953 -0.019972
+-0.1864864441 -0.001666183146 -0.015684
+-0.2090165133 0.007110112057 -0.018582
+-0.4222525809 -0.3241466578 -0.120096
+-0.4005168347 -0.296461873 -0.10446
+0.02320666606 -0.04414416928 0.000594
+0.02604990004 -0.0480504469 0.000572
+0.1047331945 -0.0630740307 0.000618
+0.1040816486 -0.06072482299 0.00062
+0.336160021 -0.4749871745 -0.018294
+0.08369979355 -0.04886415194 0.000604
+0.2531681738 0.7649327784 -0.005236
+0.08696587935 -0.04440073005 0.00062
+0.08865512067 -0.04275949756 -0.001892
+0.08946200373 -0.04529729299 0.00062
+-0.2656245734 0.0621278105 -0.0252
+-0.2903505838 0.1892897197 -0.024034
+-0.5349032532 0.1734093089 -0.224336
+-0.4959243909 0.1728804675 -0.149898
+0.1855984081 0.01444428545 0.000606
+0.1806519616 0.01043547933 -0.003448
+0.182970055 0.004979537976 -0.002104
+-0.266835428 -0.3418719025 -0.027466
+-0.2295670135 -0.371428236 -0.02571
+-0.2711207842 -0.3773779765 -0.030178
+0.2486140478 -0.6036581101 0.000408
+0.2511477004 -0.6033783758 -0.00138
+0.2294862115 -0.3571322969 -0.04533
+-0.3132656003 0.2577014577 -0.025812
+-0.3354086317 0.3037345579 -0.025794
+-0.4413532039 0.1870816927 -0.02869
+-0.45838244 0.1988336102 -0.029304
+-0.0903734651 0.8351196301 -0.027806
+-0.08055416923 0.8323812388 -0.033832
+-0.08169182268 0.8432156682 -0.054864
+-0.1252938962 -0.6945261496 -0.008494
+-0.1168006429 -0.6941482843 -0.006966
+0.03690771838 -0.07896902633 -0.003394
+0.03459355957 -0.07856538095 0.000618
+0.033123311 -0.07916449547 -0.000342
+0.3536590421 0.07350334226 -0.261116
+0.350452409 0.06497332689 -0.231068
+0.3446320016 0.0711536331 -0.207472
+0.1439588678 -0.1306198512 0.00062
+0.1100249562 -0.1137187092 0.00062
+-0.3323286492 -0.1549876595 -0.049248
+-0.3097904859 -0.1577358569 -0.036174
+-0.3158396518 -0.137717873 -0.040798
+0.1479495676 0.04623329245 0.00012
+0.1452402118 0.04688032354 0.000602
+0.1452883335 0.04999760467 0.000566
+-0.1336148181 -0.8068854503 -0.003796
+-0.1321538868 -0.8178477887 -0.004334
+-0.1234243156 -0.8232581693 0.00062
+0.1257134963 0.02484864621 -0.043152
+0.1326506701 0.02542162395 -0.03708
+0.1299248102 0.01922365772 -0.044536
+0.2734591114 -0.5894342436 -0.002784
+0.2708831929 -0.5923824389 0.00062
+0.2663290895 -0.5861029448 -0.003222
+0.7101301605 -0.2722423469 -0.085704
+0.6491119224 -0.2929393804 -0.066308
+0.09660192629 -0.09743632328 -0.002104
+0.1016363947 -0.1026649533 -0.002436
+0.1024144461 -0.09448096344 -0.003714
+0.2312022153 -0.02608346677 -0.136864
+0.2191375966 -0.02006640372 -0.118138
+0.2300705999 -0.01549126091 -0.055844
+0.03149600602 -0.06601872068 -0.005336
+0.04893275927 -0.01354286361 0.00062
+0.04960072179 -0.007254044841 -0.01654
+0.05396885958 -0.01327121556 0.00061
+0.04454043241 -0.05778420743 -0.002082
+0.04308314479 -0.05761559763 -0.002972
+-0.2922381608 0.5338715984 0.000618
+-0.1438305785 -0.7166987245 -0.007564
+-0.1348011604 -0.7091212095 -0.006934
+0.1124367597 0.1333230002 -0.013984
+0.1139367229 0.1419021026 -0.012282
+0.1119268486 -0.1089677005 -0.001254
+0.1191148933 -0.1055881996 -0.002868
+-0.1408577522 -0.5219379611 0.000444
+-0.1416491657 -0.5322075103 -0.0019
+0.07312265367 -0.02230846271 0.00062
+0.07338930232 -0.0163304503 0.00062
+0.06743664132 -0.02152812395 0.000618
+0.293497654 0.006522022996 -0.014578
+0.3001789858 0.00622617865 -0.070566
+0.5719821525 -0.2692688646 -0.039166
+0.5537606018 -0.2580591266 -0.024374
+0.5531093473 -0.2768741717 -0.023876
+0.0728588933 -0.03771918047 0.000618
+0.07161235809 -0.03386941109 0.00062
+0.07080332488 -0.03709223497 -0.00335
+0.0319317589 -0.02522340723 0.000614
+0.03148255716 -0.02783157258 -0.00138
+0.03567667797 -0.02654775712 0.00061
+0.08036637298 -0.0398990885 -0.00938
+0.07639862383 -0.03881402874 0.000608
+0.07888961482 -0.04205833771 0.00062
+0.2986937777 -0.5863592251 0.000618
+0.2984146072 -0.5835557504 -0.001642
+0.2895768343 -0.5853992919 0.00062
+-0.2443596968 -0.4720699556 -0.032146
+-0.237197775 -0.4999274231 -0.033416
+-0.2162381424 -0.477494906 -0.029708
+0.06901062768 0.9759927309 -0.02048
+0.01746442916 0.9346218005 -0.091306
+0.8223048621 -0.1908627101 -0.099574
+0.3150949598 0.4821315421 -0.106546
+0.06013483931 -0.07636111689 0.000612
+0.06153387958 -0.07698470513 0.00062
+0.3511654403 0.3374941951 -0.080396
+0.3415601964 0.3500043971 -0.064602
+0.3417058476 0.03118019566 -0.252854
+0.3389396555 0.03779618105 -0.1746
+0.09052960095 -0.04134025041 0.000612
+0.09454610362 -0.04458465416 0.00062
+0.2548438125 -0.5962879398 -0.002144
+0.2529919304 -0.5990877124 8e-06
+0.2554242464 -0.6004219741 0.000616
+-0.7300921711 -0.1578248451 -0.127064
+-0.7003725337 -0.1834332525 -0.139298
+-0.6866269361 -0.1506457068 -0.138944
+-0.3250129879 -0.1787043704 -0.042136
+-0.3029402258 -0.1740104232 -0.032078
+-0.1711930571 -0.4208145987 0.000618
+-0.1833595616 -0.436674996 0.000618
+-0.1817472666 -0.428225608 -0.001716
+0.3609747912 0.3195237132 -0.095088
+0.3653745359 0.2975258109 -0.125008
+0.3860696446 0.3146177943 -0.186296
+0.3332108623 -0.6246188975 -0.01209
+0.3340303161 -0.6102584528 -0.013036
+0.3294745172 -0.6165580668 -0.01078
+0.1460080516 0.0451534532 0.000602
+0.1433971628 0.04700315711 -0.004434
+0.0415107779 -0.09745237821 -0.000804
+0.04209258673 -0.09606175353 0.000618
+0.01350104975 -0.07516535339 -0.001244
+0.01428687849 -0.07505462024 0.000608
+0.01378523806 -0.07419924531 -0.001966
+0.172479757 -0.0191479108 0.000618
+0.1772252375 -0.01174985468 0.00062
+0.1772965301 -0.01551985855 -0.00542
+-0.2915850106 -0.2577007618 -0.03278
+-0.3085582796 -0.2545720287 -0.034908
+-0.3045473088 -0.2733398456 -0.036532
+0.350085368 0.4829929902 -0.167418
+0.3303815758 0.4747200995 -0.094746
+0.3445112728 0.4568380604 -0.153416
+-0.02988466325 0.2346418184 -0.002962
+-0.02661507727 0.225305735 -0.004734
+0.6807923672 -0.03335646808 -0.098656
+0.6777645028 0.02762656194 -0.275408
+0.6279278784 -0.01065498949 -0.24993
+0.8334613479 -0.0564506493 -0.064852
+0.8356686878 -0.1015872061 -0.058888
+-0.003128894106 -0.05022775828 0.00061
+-0.005490201372 -0.04951691098 -0.001784
+-0.2202462004 -0.2481874771 -0.008568
+-0.2134722568 -0.2574332376 -0.010636
+-0.2082931207 -0.2465086343 0.00062
+0.2913052701 -0.579234265 -0.003098
+0.285666746 -0.5830760886 -0.002828
+0.2844392053 -0.574704715 -0.003632
+-0.2585427967 0.4626797641 -0.005832
+-0.3357537156 0.6219747757 0.000618
+-0.3341720266 0.6084105584 -0.0042
+-0.1585257619 -0.7821834235 -0.021868
+-0.1716726306 -0.7910244754 -0.030912
+-0.1507004653 -0.8075449629 -0.014214
+0.2958463868 -0.4896103669 -0.030474
+0.2831536032 -0.4801956318 -0.016456
+0.2818905169 -0.4952412685 -0.014434
+0.06191697073 -0.01071515106 -0.00338
+0.0656462532 -0.01492199703 0.000598
+0.04537229144 -0.02711897087 0.000612
+0.04265600954 -0.02675706675 -0.003004
+-0.1889027859 -0.3249827356 -0.00951
+-0.2002234325 -0.325811831 -0.016248
+-0.1952755984 -0.337739803 -0.009666
+0.4028154798 0.4283069754 -0.313042
+0.4508664025 -0.2372355207 -0.116772
+0.3534267951 0.5084813337 -0.177632
+0.3701308254 0.4916344391 -0.267008
+0.3801095752 0.5155333157 -0.246666
+0.05638165869 0.06473795465 -0.026012
+0.07434883324 0.0697880195 -0.02859
+0.06217150099 0.05669950061 -0.028152
+0.09488764166 -0.081055713 -0.001208
+-0.1025651316 -0.1259184005 0.000606
+-0.09543420807 -0.119485058 -0.004864
+-0.1045373317 -0.1212896801 0.00062
+0.5076421763 0.2129972294 -0.564486
+0.4860877578 0.1684993478 -0.5636
+0.4787263599 0.2169151767 -0.482754
+0.09012818407 -0.04714254052 0.00062
+0.08980926524 -0.0491157551 -0.001282
+0.09062245538 -0.04930492175 -0.001714
+0.2540562962 -0.6966947709 -0.00309
+0.2547431967 -0.7065246371 -0.004618
+-0.0662831516 0.1572999519 -0.015068
+-0.03387813439 0.1482131154 -0.016298
+0.03391137487 -0.0508737196 -0.006298
+-0.1205636552 0.7860128307 0.000318
+-0.1075267984 0.7886066114 0.000496
+0.2670925402 -0.3922431751 -0.118718
+0.2621624922 -0.3750081505 -0.157828
+0.02380998296 0.02257021351 -0.015232
+0.0131096714 0.02642152741 -0.01582
+0.02353785829 0.0350157752 -0.022314
+-0.1462304608 0.7825349206 1.4e-05
+-0.1465449354 0.7885861187 -0.003836
+-0.1529317458 0.7815880454 -0.00038
+-0.1051095103 -0.09262555113 -0.007156
+-0.1274769328 -0.09713162162 -0.00592
+-0.1192409649 -0.1041423422 -0.00486
+-0.2382701276 -0.1784680932 -0.00732
+-0.2460345164 -0.1711240635 -0.00938
+-0.1441033065 0.7654626062 0.00062
+-0.2844387816 0.5492300385 0.00062
+-0.267646911 -0.002648814147 -0.0224
+-0.2662124943 -0.01971780793 -0.02437
+-0.2551754457 -0.008227673533 -0.022106
+-0.4735029603 0.271350929 -0.03912
+-0.4646715109 0.2378292326 -0.019092
+-0.4455240148 0.244408418 -0.028868
+-0.3870686393 0.4332068689 -0.031612
+-0.1567518853 -0.09780005614 -0.00538
+-0.1477637319 -0.1074707779 -0.00472
+-0.1454095872 -0.0975093243 -0.005548
+0.2803666304 -0.673817941 -0.004586
+0.2781840556 -0.682823087 -0.013048
+0.2717336145 -0.6739213866 -0.003562
+-0.04798188185 0.1985862014 -0.00679
+-0.04314691174 0.1890081882 -0.0106
+0.2515307039 -0.7148069824 -0.006098
+0.2498003174 -0.4011396782 -0.022054
+0.2619829393 -0.4127415333 -0.03572
+-0.4223996808 0.4522910077 -0.139634
+-0.149793338 0.2258287803 0.000548
+-0.2127122209 0.3448880008 0.00062
+0.07572743432 -0.02516841444 0.00062
+0.07704992131 -0.02308185383 -0.003168
+0.07887081082 -0.02526521653 -0.00538
+0.1902859188 -0.2154470031 -0.009
+0.1989678512 -0.1997764349 -0.01938
+0.1997157768 -0.2151100446 -0.016248
+0.03237201729 0.06269678113 -0.02517
+0.01474143127 0.07515707546 -0.026076
+0.02824737053 0.07347812963 -0.026086
+-0.2764360323 0.5224541869 0.000618
+-0.2688045689 0.5126650279 0.000292
+0.4619388216 0.3110395811 -0.391188
+0.4541505552 0.2816369106 -0.356896
+0.4893254933 0.2861775291 -0.45455
+0.3416278424 -0.06402446103 -0.479438
+0.2541709321 -0.1105920074 -0.08478
+0.2489782979 -0.09489397592 -0.080306
+0.05789365348 -0.07603859153 -0.002348
+0.3209046167 0.1196763867 -0.006188
+0.3180559407 0.1259060438 -0.002492
+-0.5302787016 0.03938733867 -0.162118
+0.2076793523 -0.2490431877 -0.020422
+-0.2552274458 -0.1082442357 -0.018804
+-0.233392901 -0.1160453839 -0.014066
+-0.2340142736 -0.09773541546 -0.015902
+0.02822090843 -0.05925386623 0.000618
+0.02539166639 -0.06163386721 0.000618
+0.02660540782 -0.05654951302 0.00062
+0.1249923845 0.05664882018 -0.022412
+0.1255248942 0.05017984786 -0.028158
+0.1298391544 0.05367769087 -0.01407
+0.03373212411 -0.0749355843 0.000612
+0.03503400306 -0.07674296717 -0.004708
+-0.4386128179 0.5186035005 -0.121166
+-0.450256145 0.5006713969 -0.185972
+-0.4306592059 0.4978972151 -0.111938
+0.136458276 0.009207343409 -0.032292
+0.1408050268 0.01501611259 -0.01634
+0.1342764731 0.01501112996 -0.03276
+-0.06788532869 0.8058473762 -0.005292
+0.1103345726 0.1497744919 -0.012406
+0.1510673998 -0.1092327049 -0.009482
+0.1567748702 -0.1022792868 -0.01221
+0.006588907852 -0.03641058828 -0.004894
+0.006306223707 -0.03241114045 0.000606
+0.009706839322 -0.03854771909 0.00062
+0.4105670947 0.08533775028 -0.41819
+-0.2037531555 0.3832169539 0.00062
+-0.2061494471 0.380941145 0.000618
+0.009403200981 -0.04576953595 0.00062
+0.005884267623 -0.04341876905 -0.003082
+-0.1736429797 0.7772212677 0.00062
+-0.1704841252 0.7797771295 0.00062
+-0.1708097914 0.773121564 0.00042
+-0.1377875385 0.775358782 0.00062
+-0.1378054153 0.7773599696 0.00062
+0.1283808275 0.08647352311 0.00062
+0.1274699372 0.08014761509 0.000616
+0.1350380477 0.08527314531 -0.005372
+0.04985009142 0.245998181 0.00062
+0.05396480124 0.231807319 -0.00386
+0.5021826983 -0.2289622651 -0.054978
+0.3256954571 -0.5648176354 -0.012796
+0.3166817087 -0.5694162324 -0.010732
+0.319140283 -0.5583801906 -0.012486
+-0.02252276507 -0.00993553895 0.00062
+-0.02438549985 -0.002214029515 0.000618
+-0.2254358747 -0.1538348357 0.000616
+-0.2246875051 -0.1425842854 0.000616
+-0.2801473061 -0.5663116818 -0.095386
+-0.2602420649 -0.5514517946 -0.0588
+-0.2545618316 -0.5798984202 -0.075918
+-0.164624758 -0.02408551741 -0.013486
+-0.1892586483 -0.04517291143 -0.0131
+-0.1735836877 -0.04910236171 -0.012178
+0.008584161164 0.8179765948 0.00062
+-0.009213991765 0.8155914741 0.00062
+-0.02841584732 0.8072824826 0.00062
+-0.1436404967 -0.002902427452 -0.013294
+0.1087166625 -0.01256325061 -0.024688
+0.1054027402 -0.02091911545 -0.0138
+0.11246691 -0.02180632072 -0.038424
+0.001560382991 0.8420465039 -0.00943
+0.2948144663 -0.6219019446 0.00062
+0.2906638915 -0.6207850259 0.00062
+0.2924645415 -0.6204074754 0.00062
+-0.2399364384 -0.5967203395 -0.068614
+-0.2313821183 -0.5820290001 -0.047664
+0.02722460447 -0.04474270743 0.00062
+0.02746687405 -0.0458155228 0.00062
+-0.2492860305 0.2214124666 -0.006036
+-0.2504093103 0.2313025012 0.000616
+-0.007941463682 0.1505492271 -0.019594
+-0.02818292361 0.1379013207 -0.018476
+-0.02347679969 0.1263906391 -0.01938
+0.2585400732 -0.5877074526 -0.00324
+0.258703905 -0.5933421136 -0.002096
+0.2640665895 -0.5923878217 -0.002384
+0.2774057087 0.560952006 -0.024224
+0.2898321903 0.5698637121 -0.028658
+0.05763230323 0.01124740987 -0.023562
+0.07030371281 0.01234701435 -0.02606
+0.06506061807 0.003646695904 -0.017126
+0.08178977606 -0.03662769464 0.00054
+-0.227559249 -0.7404989678 -0.102916
+-0.208001939 -0.7447982521 -0.042832
+-0.203518983 -0.7215719913 -0.037584
+-0.002069625563 -0.03580147873 -0.00938
+-0.004389639362 -0.03880060594 0.00062
+-0.00335926271 -0.03950083727 -0.000368
+0.08064208123 -0.05801986114 0.000614
+0.03588394934 -0.02365041644 0.00062
+0.03795277254 -0.02035341518 -0.00164
+0.0348391553 -0.01847040518 0.00062
+-0.6158870387 0.2909228144 -0.293506
+-0.5905094439 0.3257697242 -0.319428
+-0.573922215 0.2926551717 -0.295732
+0.06423712687 -0.02949603217 0.00062
+0.06608707498 -0.03223400348 -0.00319
+0.06331769218 -0.03651757509 0.00062
+-0.1631991297 -0.8725991524 -0.039418
+-0.1593365906 -0.8889217238 -0.047896
+-0.1736908881 -0.8791982209 -0.04552
+0.03959353216 -0.0798148823 -0.00191
+0.03912001154 -0.07794910298 0.000614
+0.3031698094 -0.5834010492 -0.002174
+0.299460721 -0.5783300711 -0.00265
+-0.0009982744706 -0.0420423294 0.000616
+0.1120074881 0.04910539648 -0.031018
+0.1188747778 0.05321747935 -0.028728
+0.2267401801 0.5206619798 0.00062
+0.2660081832 0.4622676757 0.00062
+0.3342139205 -0.07722342384 -0.496268
+0.3310448022 0.6668001152 -0.019298
+0.3180648729 0.6712660392 -0.010264
+0.3219674097 0.6574096388 -0.01425
+0.142940418 0.03882996191 -0.006018
+0.1404706117 0.03627704864 0.000596
+0.1436460319 0.03506583608 0.00062
+-0.0005533137385 -0.05067100749 0.00062
+-0.005285780776 -0.05524289463 0.00061
+0.001755563516 -0.05889231685 0.00062
+0.09210644259 -0.049512857 0.000612
+0.09116208812 -0.05047470771 -0.003256
+-0.8081903772 -0.03513298381 -0.137124
+-0.7770412082 -0.06133096629 -0.1318
+-0.7815556661 0.04835063024 -0.185032
+0.3816106742 0.1568886049 -0.22708
+-0.2016390117 -0.4748618676 -0.024322
+-0.1885798284 -0.4717718455 -0.016934
+-0.09364873215 0.8480864803 -0.072834
+-0.1030274143 0.8391503081 -0.035872
+0.4220810655 0.04581552428 -0.540102
+0.4205014298 0.05845402711 -0.496754
+0.4098254395 0.04864831498 -0.440118
+0.2906185573 -0.6155487099 0.00062
+0.03675016814 -0.02625682388 0.000616
+0.03867817547 -0.02751012528 0.00062
+0.0398973491 -0.02608330339 -0.005098
+0.1965714386 -0.006553967558 0.000616
+0.1878093023 0.00384041384 0.000618
+0.3468677249 -0.5486298607 -0.017714
+0.2758171346 -0.113135812 -0.27622
+0.2920488497 -0.07670513238 -0.430746
+0.8676951358 -0.1328954565 -0.077446
+0.8553596541 -0.1102260881 -0.063476
+0.8369817401 -0.124211677 -0.062338
+0.2663050511 0.556204546 -0.018946
+0.2547114713 0.5604647222 -0.0142
+0.3426873423 0.3214515987 -0.0535
+0.00397475115 -0.02073387217 -0.007864
+0.009822850536 -0.01747531496 0.000608
+0.004718510719 -0.014017792 -0.009228
+-0.1575732004 0.7803239656 0.000174
+-0.1538625932 0.7776638918 0.000254
+0.03580967163 -0.06070856749 0.00062
+0.0386533333 -0.05887040142 0.00062
+0.4000503174 0.404207002 -0.310754
+0.3817280509 0.4222667129 -0.296222
+-0.1388516055 -0.06359092315 -0.00946
+-0.1367176969 -0.07752510888 -0.007306
+0.2771309604 0.7092579116 0.000616
+0.2435611442 0.5784104031 -0.011984
+0.02926431643 -0.07744882931 -0.0011
+0.03102057906 -0.0769280285 0.000618
+0.03063395441 -0.07620826185 -0.00304
+-0.146554438 -0.9010116483 -0.019412
+-0.1416156421 -0.8863258973 -0.01345
+-0.1983243714 0.209858514 0.00062
+-0.1797168623 0.2107015967 0.00062
+0.02881609711 -0.07326734749 0.00062
+0.02940390871 -0.07500819631 -0.001266
+0.2111324881 -0.1885153898 -0.020396
+0.2289317039 -0.1992693071 -0.04824
+0.2275581485 -0.1818534697 -0.058986
+-0.1361842599 0.2103474545 -0.00338
+0.1210249372 0.1010110871 -0.00866
+0.1273149681 0.09787024547 0.00062
+0.02925528332 -0.009965292907 -0.006536
+0.03021275414 -0.0150443112 0.000612
+0.03447008833 -0.01278327911 -0.013502
+0.2418911897 -0.6230363524 -0.000316
+0.2435008737 -0.6207031562 0.00062
+0.2455135387 -0.6227804358 0.00062
+0.04272380836 -0.01792426837 -0.003036
+0.04552995109 -0.02180270437 0.00062
+0.04662832579 -0.01813296969 0.000604
+0.1656090753 -0.1318710524 0.00062
+0.1700851278 -0.1320427353 0.00062
+0.1679224309 -0.1286691657 0.00062
+-0.6030032661 -0.3388983788 -0.1721
+-0.629737706 -0.3166134246 -0.16707
+0.07339742201 -0.06477759848 -0.00538
+0.07489836533 -0.06239114696 -0.00538
+0.07178579139 -0.06311423971 0.00062
+0.08655231572 0.08975304243 -0.024704
+0.07545281515 0.0981590841 -0.0255
+0.07256519046 0.08281051888 -0.026764
+-0.4323792474 0.1687234058 -0.02986
+-0.1349533483 -0.584638979 -0.00882
+0.0825391444 0.1095012078 -0.023722
+0.07168128443 0.1109700676 -0.023338
+0.2689169343 0.6748711554 -0.006652
+-0.1798726242 -0.09558160915 -0.001274
+-0.1691020153 -0.102894182 -0.004784
+-0.1680076675 -0.09172179662 -0.004068
+0.07014560189 -0.06141686144 0.00062
+0.07038625604 -0.06379384948 0.00062
+0.07462075162 -0.04139905786 0.00062
+0.07427005372 -0.03888457188 -0.00538
+0.07211156437 -0.03944348909 -0.00307
+0.06794242283 -0.0788848605 -0.000384
+0.05232442098 0.08658714237 -0.025312
+0.04525254714 0.09486058676 -0.023542
+0.03895535561 0.08283250491 -0.023822
+-0.3827941953 -0.1048753188 -0.091824
+-0.3673737842 -0.1283181423 -0.075652
+0.2081280199 -0.2634307557 -0.033802
+0.1997142497 -0.273409514 -0.010774
+0.1968446859 -0.2602636406 -0.017296
+0.0133888035 -0.07633517892 -0.00229
+0.04188754747 -0.09972004676 0.00062
+0.04401970294 -0.101989772 0.000618
+0.04470538302 -0.09656162156 0.00062
+0.1497673168 0.04243648802 -0.003268
+0.1502985171 0.03993959007 0.000614
+0.1474479843 0.04208110969 -0.001948
+0.07927814292 0.2019293401 -0.010492
+0.08700283829 0.2091301882 -0.00575
+0.07799831842 0.2115536626 -0.008122
+-0.06858936696 -0.06784645912 -0.009248
+-0.04142341824 -0.04928686124 -0.009822
+0.3352045598 0.2312877699 -0.02979
+0.3252432438 0.2343561662 -0.022634
+0.3235360483 0.2156619443 -0.01924
+0.09573612444 -0.04784384654 0.000186
+0.09434848103 -0.04905939554 -0.00524
+-0.2969398321 0.5596913245 -0.003394
+-0.2959507967 0.5491126888 -0.00586
+0.2588575946 -0.5994559727 -0.00048
+0.2573337452 -0.5994206074 -0.00104
+0.2569295437 -0.6011771129 0.00062
+0.1488390723 0.03272497931 0.00062
+0.1513832057 0.03703511448 0.000618
+0.1538524128 0.03535644875 0.00052
+0.2862032021 -0.587416707 0.000618
+0.2798601332 -0.5822642768 -0.00346
+0.211203067 -0.02750742999 -0.100918
+0.2195171777 -0.03315162415 -0.063722
+0.09399357083 -0.07346374729 -0.000984
+0.09701516105 -0.07577239721 0.00062
+-0.4479303965 -0.06851543634 -0.073058
+-0.4705801298 -0.06568945492 -0.089212
+0.2666608566 -0.5773213643 -0.003902
+0.03278631788 0.8204142643 0.00062
+0.02920196081 0.820150131 0.000588
+0.02936702211 0.8176594315 0.00062
+-0.219685965 -0.7777783789 -0.09636
+-0.2497108286 -0.7875228026 -0.160172
+0.09584746034 -0.01205236677 0.00062
+0.09038104321 -0.01362378513 -0.003224
+0.09253869157 -0.008073107814 0.000618
+0.1459828194 0.03143676774 -0.00449
+0.1478124677 0.03582156981 -0.001944
+0.1916902372 -0.1075387307 -0.022794
+0.05356105273 0.9168928564 -0.011402
+0.05807483651 0.929496116 -0.012522
+0.06449876321 0.9188915002 -0.006446
+0.2024091209 -0.02654525032 -0.083796
+0.1941444141 -0.03306578 -0.03938
+0.2533872463 -0.6878537891 -0.001602
+-0.3182257633 -0.3793155691 -0.040672
+-0.2430699926 -0.09091910672 -0.017226
+-0.2634621352 -0.09877566289 -0.022058
+0.07637171197 -0.05055950353 0.00062
+0.07721626689 -0.04947707828 -0.00291
+0.07707812249 -0.04721876454 0.000608
+0.7238319672 -0.221468937 -0.047872
+0.7446285965 -0.2348264983 -0.075674
+-0.1836900834 -0.3131731682 -0.007876
+-0.1794016068 -0.3015669627 -0.006358
+-0.1956827054 -0.2957357898 -0.010242
+0.3476904107 0.2077045805 -0.075446
+0.3436687791 0.1919673586 -0.03938
+0.3316793025 0.2043427766 -0.024398
+0.2814065141 0.7227244063 -0.003346
+0.504234923 -0.5017871773 -0.111162
+0.4754282233 -0.457796796 -0.110874
+0.4705663974 -0.481169282 -0.111036
+0.03243351929 -0.07599969043 -0.002806
+0.1005296212 -0.03526061395 0.000618
+0.1002645491 -0.02996086464 0.00062
+0.3156790495 -0.6320845327 0.000616
+0.3172947821 -0.6295247662 0.00062
+0.3132247805 -0.6324366186 0.000618
+0.2311192627 -0.04017729591 -0.142624
+0.07922154361 -0.05370658858 0.00062
+-0.1434246352 0.08152120585 -0.015596
+-0.1322543378 0.07860487568 -0.015746
+0.138013984 0.07846266078 -0.007378
+-0.009096540427 -0.04915903097 0.000566
+0.2157571616 -0.3502993952 -0.069014
+0.6048573839 0.1748768114 -0.606108
+0.5859380251 0.1348615702 -0.652406
+-0.5848813324 0.2073359121 -0.272068
+0.04117848527 -0.08899074262 0.00062
+0.3405860126 0.697155649 -0.026014
+0.4552357319 0.5267884427 -0.422906
+0.5812776183 0.3897169755 -0.58885
+0.0970378446 -0.0467870225 -0.001344
+0.09654847456 -0.04829427188 0.000606
+0.09747324322 -0.04940296196 -0.000252
+-0.01513991025 0.2447169761 -0.001526
+0.1198405334 0.04543357074 -0.036286
+0.1155823861 0.03209341157 -0.027134
+0.1134390832 0.04023411439 -0.028874
+0.05345159439 -0.06944347899 0.00062
+-0.1013251436 0.04673522978 -0.014458
+-0.1118214725 0.03152001071 -0.012818
+-0.1176047845 0.03808859207 -0.012844
+0.1019151075 -0.01567319074 -0.018184
+0.1018184838 -0.02080857968 -0.01071
+0.09830174504 -0.0184178469 0.00062
+0.3346699191 0.004390648139 -0.379732
+0.3379217286 0.0151910481 -0.305614
+-0.3283820866 -0.4919816749 -0.100828
+-0.3030892398 -0.5128935296 -0.082562
+-0.3006061555 -0.4811226343 -0.062504
+0.348004035 0.05790311462 -0.206756
+0.3372062526 0.06840372143 -0.150384
+0.01739215616 -0.03617819561 -0.001184
+0.02088080379 -0.03797565099 -0.007462
+0.372526699 0.04546424024 -0.396888
+0.3856714755 0.05754380448 -0.421078
+0.3663780487 0.06217759427 -0.329802
+-0.006034685607 -0.03553992423 0.00062
+-0.004673454487 -0.03323214239 0.00062
+0.1325877463 0.04848865771 -0.019706
+0.1354643197 0.05399419694 -0.012606
+0.1374491636 0.04973040614 -0.013642
+-0.1120089394 0.813524952 -0.00868
+-0.1088566124 0.8308597809 -0.018524
+-0.1023198654 0.8140960745 -0.00908
+-0.338302297 -0.133265468 -0.056028
+-0.3420910203 -0.1124421936 -0.060736
+-0.307587265 0.5449984303 -0.008484
+-0.299747429 0.5366204935 -0.00669
+0.3666787143 -0.4679656754 -0.046704
+0.3738785822 -0.4853079596 -0.019012
+-0.2521652858 -0.4216642161 -0.028466
+-0.2307881328 -0.4014765422 -0.027206
+-0.2568045284 -0.4049515446 -0.030386
+0.1128338249 0.1858070322 0.000618
+0.1033753149 0.1880060076 -0.005524
+0.1029785375 0.1791072131 -0.005492
+0.1826900695 -0.0401847266 -0.030438
+0.1668881754 -0.04048042279 -0.039688
+0.1615677863 -0.0534510336 -0.060758
+0.02125047066 -0.02191891119 0.00062
+0.308295527 0.4207672165 -0.026144
+0.3415551483 0.137836123 -0.03395
+0.3444964018 0.1196799768 -0.045582
+0.3314645915 0.1327513578 -0.021676
+0.6055963736 -0.2954950953 -0.05156
+0.6255489877 -0.3068905324 -0.05961
+0.6260963986 -0.2823020313 -0.057542
+-0.05468870731 -0.128043144 -0.005914
+-0.04741960667 -0.118953612 -0.00653
+0.8900513405 -0.0009216998688 -0.065644
+0.9002158203 0.02762289147 -0.073316
+-0.1087278565 -0.1018904659 -0.006356
+0.1406036573 0.05569242471 -0.007112
+0.04477424792 0.06390737605 -0.02624
+0.03900624263 0.07164675544 -0.026272
+0.356373644 0.05733511951 -0.29086
+0.3651979758 0.05140233294 -0.354246
+-0.6392243964 -0.2518514078 -0.163028
+-0.719766535 -0.2453296545 -0.129652
+-0.1583116172 -0.04294486426 -0.011212
+0.08145797507 0.01156985908 -0.028006
+0.09169419537 0.008725577474 -0.02789
+0.09791732526 0.01544861093 -0.040202
+0.155469905 -0.06494438098 -0.028924
+0.1483985518 -0.05433094525 -0.02366
+0.02930048027 -0.0720175217 -0.001778
+0.2381913151 0.6389481407 -0.009324
+0.2443109858 0.6468348843 -0.007364
+-0.2376834665 -0.2088838727 -0.006628
+-0.2320236065 -0.213552291 0.000616
+-0.232418953 -0.2020897527 0.000618
+0.07681237146 0.03640887545 -0.030902
+0.07697211205 0.02329174304 -0.026632
+0.06623137735 0.03068294946 -0.026458
+0.08797111962 -0.03748710312 0.000606
+-0.4157280544 -0.1752131814 -0.110714
+-0.3837203132 -0.1776846632 -0.082602
+0.02861592588 -0.03069936541 0.00062
+0.0249799228 -0.03212656577 0.000618
+0.340139889 -0.5576463485 -0.014906
+-0.1394937667 -0.1106117124 -0.002332
+-0.1450462384 -0.1163253071 -0.00268
+-0.1388943678 -0.1182985658 0.000618
+0.19126965 -0.294589909 -0.003088
+-0.1571336461 -0.7547264761 -0.019796
+-0.1557938316 -0.7631977418 -0.019542
+0.001507359992 -0.07450511555 0.000612
+0.001002689416 -0.07234399102 -0.000284
+-0.001467177046 -0.07411014867 0.00062
+-0.05062349311 0.132393151 -0.017714
+-0.3459898468 -0.2854096299 -0.053508
+-0.3714912741 -0.2855191436 -0.082394
+-0.3544098706 -0.3074047485 -0.061176
+0.1890323041 0.6124065066 -0.001252
+0.3015642803 0.3025519498 -0.009536
+-0.1601854441 -0.111687852 -0.004164
+-0.4445225507 0.3725309027 -0.154008
+-0.06219601376 0.1247301714 -0.016814
+0.04388275276 -0.01353805439 0.000612
+0.04532232143 -0.01106062186 0.000614
+0.7526463699 0.05642649817 -0.1861
+0.7570463625 0.02973181254 -0.109644
+-0.01594875286 0.2228480029 -0.005392
+-0.01475368968 0.2136150357 -0.007742
+-0.004552151098 0.2186862 -0.005544
+0.2615002757 0.7515093215 -0.005786
+0.2663859437 0.7457124541 -0.007128
+0.2708833708 0.7532399799 -0.009066
+0.2948339719 -0.6544362834 -0.003598
+0.2959605617 -0.6626203025 -0.005236
+0.3021879965 -0.6568042763 -0.00655
+0.1994878699 0.5920280481 -0.006152
+0.2071511395 0.5948285456 -0.007708
+-0.06914493095 0.7943846532 0.00062
+-0.05371190376 0.7981468153 -0.000202
+0.1811920415 0.6112126854 0.00062
+0.01622176837 0.001397734911 -0.011232
+0.02647227258 0.0004493057898 -0.019368
+0.02508390708 0.01078324599 -0.014926
+0.2664506395 -0.09443591819 -0.254568
+-0.2494960058 -0.7232390416 -0.147482
+-0.2753641113 -0.7349690181 -0.186214
+0.1522332468 0.04314218286 -0.001226
+0.1505543229 0.04386060332 -0.001226
+0.1521767396 0.04453368535 0.00052
+0.2987536422 -0.4709704524 -0.03591
+0.3180567623 -0.4719103014 -0.024854
+0.3107814718 -0.4550208563 -0.117574
+0.506669093 -0.417668796 -0.09454
+0.5285531959 -0.432073488 -0.091886
+-0.2093102039 -0.2654843835 -0.011792
+-0.2249456283 -0.2586413478 -0.016302
+0.03902899743 -0.03814149509 -0.00338
+0.03735553794 -0.03850128767 -0.003674
+0.03861074723 -0.04052131143 -0.00338
+-0.158568797 0.7750685074 -0.000708
+-0.1573881195 0.7781141819 -0.00018
+-0.1608986668 0.7779793163 0.00052
+-0.2378110625 -0.2276658063 -0.012684
+0.1014831968 -0.07119868086 0.000616
+0.0989818408 -0.07734177825 0.00062
+-0.3852163463 -0.0008518065459 -0.053414
+-0.3814960935 0.03802464967 -0.044886
+0.0885724114 -0.02168997684 0.000618
+0.08746032606 -0.02114202504 0.00062
+0.08575222372 -0.02302758276 0.00062
+-0.1648174474 -0.7160369575 -0.01713
+-0.1640078442 -0.7050185312 -0.022588
+-0.1750648872 -0.7104060892 -0.024306
+-0.2014601275 -0.2886587919 -0.012462
+-0.2204752019 -0.2807717745 -0.018244
+-0.2108371464 -0.3056731488 -0.018788
+0.008964860862 -0.06065813002 0.00062
+0.01093993558 -0.06274060626 -0.003686
+0.06715780784 -0.03796807286 -0.00488
+0.06601055252 -0.0397379379 0.00062
+0.06952635095 -0.03923046095 0.00062
+0.3066333974 0.2586079441 -0.014332
+0.3001484647 0.2632437228 -0.009722
+0.3017232947 0.2531181225 -0.009824
+0.09412112018 -0.0307123248 0.00062
+0.09112833218 -0.03288812003 0.00062
+0.002574608092 0.1423908595 -0.02087
+-0.08530571364 0.8093917429 -0.007648
+-0.07693326852 0.8027985591 -0.00412
+0.01000138915 0.8629738437 -0.013772
+0.005244554222 0.8724940735 -0.01744
+-0.130509776 0.153406566 -0.010076
+-0.1316305443 0.1640604969 -0.007938
+-0.1216590135 0.1590904822 -0.0084
+-0.1530902217 -0.04747956066 -0.010888
+-0.1520291169 -0.04063740601 -0.010444
+0.0007398078565 -0.03076627432 -0.006204
+0.03768542554 -0.05014093586 -0.003256
+0.03662785911 -0.04992677661 0.00061
+0.03731432463 -0.04943747813 -0.00363
+-0.267336011 0.2776656358 -0.017796
+-0.3726610071 0.4381237201 -0.025254
+-0.3781151313 0.420928687 -0.026314
+-0.01745176876 -0.01124121853 -0.002336
+-0.01997145911 -0.009820220444 0.00062
+0.08630778541 -0.02002073896 0.000616
+0.08692210293 -0.016820943 -0.002674
+-0.02377921305 -0.1195115853 0.00062
+-0.02692916178 -0.1207322779 0.00062
+-0.02697702963 -0.1222309477 0.000592
+0.007572026898 -0.0493435052 0.00062
+-0.04373204139 0.815622622 -0.00456
+-0.03889611364 0.8086385241 -0.002178
+-0.04873546647 0.8083189496 -0.004256
+0.03281097045 -0.06679916739 -0.00488
+0.03386837684 -0.06701264908 -0.002154
+0.03242605997 -0.0681678578 -0.00515
+-0.1605317384 0.2038692338 -0.004162
+-0.1771619427 0.1951016265 -0.006804
+-0.171132038 0.2058181199 -0.003224
+0.1007175339 -0.08541653455 -0.004798
+-0.1325944872 0.8147240863 -0.008202
+-0.1343660947 0.8061713883 -0.007574
+0.09718527578 -0.04513125621 0.000614
+0.09742559276 -0.0459430776 -0.000744
+-0.3988648786 0.4646940573 -0.047476
+-0.3952109019 0.490411741 -0.02888
+-0.3857739525 0.4761395387 -0.027052
+0.2239425711 -0.5281553512 -0.0063
+0.2157557098 -0.5291018531 -0.00569
+0.2284120035 -0.5467846116 -0.004836
+-0.2177783471 -0.2379862922 0.000568
+-0.2275580915 -0.2291316772 0.000616
+-0.2264406392 -0.240620268 -0.009714
+-0.3123161587 0.5703106555 -0.005768
+-0.3045733914 0.5650751776 -0.005318
+-0.3031308713 0.5743773688 0.000616
+0.04496272431 -0.04757202364 -0.004738
+0.0461785915 -0.04666838493 0.000612
+0.0466628695 -0.04803045405 -0.00133
+0.04412495745 -0.06381765566 0.00062
+0.0005241947515 0.8299624988 -0.005334
+0.394800601 0.008163757536 -0.49027
+-0.2198719192 -0.6547668288 -0.100504
+-0.2057114015 -0.6370430858 -0.06238
+-0.2512210545 -0.6507697671 -0.137492
+0.2126406339 -0.3836347026 -0.00803
+-0.1312636145 -0.001465757953 -0.011484
+-0.1473020651 -0.01352389586 -0.012966
+-0.1964981831 -0.4341829776 -0.014728
+-0.1996618947 -0.4228711696 -0.019708
+-0.1912783157 -0.4042147452 -0.013822
+0.5881010632 -0.2833216576 -0.048168
+0.5932939813 -0.2611034922 -0.060314
+-0.347846953 0.34893577 -0.024152
+-0.3977898132 0.3466658661 -0.029588
+-0.3929016748 0.3649465947 -0.02863
+0.1872075551 0.0003545839682 0.000614
+-0.3263288717 0.613867601 0.000532
+-0.3262650096 0.6049202395 -0.003608
+0.0002194185706 0.2467645304 -0.00231
+0.2486915978 -0.6077001913 -0.00085
+0.2496093798 -0.609255701 0.00062
+0.2508362815 -0.6062296726 -0.00138
+0.09477612038 -0.03936078072 0.00062
+0.09542786088 -0.04092841917 0.00062
+0.09916211242 -0.04278917935 0.00062
+0.03171797639 -0.03177911595 -0.001122
+0.03226424225 -0.03033548947 -0.001352
+-0.07843898966 0.1056648476 -0.01938
+-0.1218031226 0.1130365703 -0.018988
+-0.09086112746 0.1273872012 -0.017
+-0.1667185875 -0.1343679953 0.00062
+-0.1818931451 -0.1286955877 0.00062
+0.4713511452 -0.1092158305 -0.327626
+0.4993882019 -0.1173720501 -0.236634
+0.4982162605 -0.07176033888 -0.34863
+0.09525579235 -0.1046795976 0.00062
+0.3412957341 -0.3961084517 -0.14264
+0.2918770276 -0.5042139632 -0.024788
+-0.1505720234 -0.8510986754 -0.016972
+-0.1426881101 -0.8610586825 -0.016376
+-0.1178764851 0.2328746492 0.00062
+0.3025076781 0.3942373987 -0.024414
+0.2958425352 0.3853822661 -0.01296
+0.2921950619 0.3991003935 -0.010644
+0.04266316121 0.9136818954 -0.016164
+0.04979419966 0.9044927621 -0.009688
+0.04119217242 -0.04516860851 0.00062
+0.4175158315 0.1973213745 -0.294012
+0.4060462695 0.2202729817 -0.223216
+0.4249910994 0.214097249 -0.288962
+0.04384659545 -0.04885604974 0.000618
+-0.1641640397 -0.4961061809 -0.007312
+-0.153426641 -0.4956960328 0.000618
+-0.3095632295 0.05776603964 -0.028162
+-0.3273696124 0.04741544853 -0.032436
+-0.3134781014 0.07414721997 -0.02836
+0.2133524122 0.5396841817 -0.002708
+0.3044246431 0.6595951145 -0.008838
+0.297871951 0.6528485833 -0.009448
+0.4972897419 -0.1852768174 -0.134638
+-0.3018598886 -0.7031756896 -0.195264
+-0.271383895 -0.7009522321 -0.17092
+-0.1472234945 -0.6390699316 -0.032208
+-0.1626614164 -0.6376907328 -0.03921
+-0.1927727725 -0.09307023676 -0.001184
+-0.185203465 -0.08498787225 -0.000136
+0.075104379 0.003945989237 -0.023874
+-0.2363832067 0.4045757264 -0.007146
+-0.2358054 0.3935401154 -0.007264
+-0.2703887574 0.3489935624 -0.015574
+-0.3096380063 0.3441133647 -0.01938
+-0.3931680339 0.06615425989 -0.038014
+-0.4091337161 0.07928607386 -0.03647
+-0.4149174867 0.0544176539 -0.053394
+0.2274143362 -0.2771692482 -0.170266
+0.2137870762 -0.2760557452 -0.096696
+-0.828709472 -0.1043301295 -0.115802
+-0.7859331609 -0.1550221661 -0.116994
+0.329286432 0.0136933412 -0.216094
+0.0550054843 0.09555301081 -0.0249
+0.3356767045 0.04609429393 -0.1833
+0.3305048256 0.03869712813 -0.108254
+-0.1168535735 0.8201916658 -0.011814
+-0.04076964547 -0.1023835511 -0.007096
+-0.05434405806 -0.1046028911 -0.007578
+-0.05118372452 -0.09377528825 -0.008178
+-0.1798476824 -0.5892298976 -0.038206
+-0.1928669072 -0.5947590029 -0.042276
+-0.2308272885 0.2155781691 0.000618
+-0.2240311857 0.2125956178 0.000618
+-0.2298038207 0.2068842427 -0.00666
+-0.09684733118 0.05565826875 -0.01683
+0.02623592174 -0.06368112923 -0.00138
+0.02534925693 -0.06262748242 -0.00138
+0.02699246107 -0.061709326 -0.002136
+0.1270870851 -0.1028902459 -0.00578
+0.1334669062 -0.1102665598 -0.0025
+-0.1668047988 -0.1278097819 -0.001962
+-0.1737947872 -0.1230761129 -0.002128
+0.02766278845 0.8672509959 -0.010346
+0.02125198302 0.8542948584 -0.008954
+-0.1548867196 -0.7147739403 -0.010968
+0.0363140582 -0.04903020156 -0.00382
+0.03731562174 -0.04787046005 -0.003494
+0.339974271 -0.5387759042 -0.016232
+0.334561145 -0.529413317 -0.016544
+0.3160154499 -0.5422744622 -0.013158
+0.2101032603 -0.5215400428 -0.004806
+0.220656666 -0.5198490278 -0.006568
+-0.1406424084 -0.8541846274 -0.011656
+-0.1351693227 -0.8376065936 -0.004376
+-0.06745877357 0.2279847369 0.000618
+-0.03309024672 0.2425617725 0.00062
+-0.04021822112 0.2366810754 0.00062
+-0.2965467619 0.5269697074 -0.005744
+0.2659376672 0.4701141842 0.00062
+0.01326503834 -0.04774480179 0.00062
+0.2262072559 -0.4147535777 -0.008682
+0.2367080518 -0.4182767694 -0.012022
+0.2371772813 -0.4074744083 -0.016576
+0.1831711925 -0.001327029049 0.00062
+0.1789667093 -0.004385994464 0.00062
+0.1822574785 -0.006538798893 0.000616
+0.3377038544 0.6349372136 -0.028942
+0.3395370729 0.649216082 -0.026052
+0.2923043926 -0.6184938396 0.000616
+0.2935417863 -0.6162278019 -0.000164
+0.3042751184 -0.5695598091 -0.006062
+0.3082457832 -0.5597948682 -0.009444
+-0.02867550835 -0.1049303389 -0.005522
+0.2474308537 -0.4160205001 -0.017372
+0.08137690897 -0.02381174166 0.000598
+0.08384951882 -0.0236301698 -0.002154
+0.08264081424 -0.02217987607 0.00062
+-0.4508354617 0.1651469494 -0.032844
+0.287642071 0.3886523922 -0.005462
+0.2803384946 0.3913265361 0.00062
+0.2830697217 0.3831859897 -0.004148
+0.2008796414 -0.09097586585 -0.027936
+0.5488320945 -0.1015018876 -0.1621
+0.5163085704 -0.1355810277 -0.170692
+0.5359870461 -0.1559349977 -0.124702
+-0.1215608394 0.8139075281 -0.001534
+-0.3502464172 -0.4067190441 -0.09087
+-0.06455607817 0.0507996403 -0.01674
+-0.07766224008 0.04844792433 -0.016414
+-0.07007823754 0.03970761568 -0.01532
+0.2807610604 0.6251044407 -0.019504
+0.2911842119 0.6299231053 -0.01866
+-0.05536134369 0.04065691467 -0.016294
+-0.02569478603 0.08209707074 -0.020796
+-0.03519472683 0.06172902429 -0.026792
+-0.02106091184 0.06148233006 -0.022324
+0.004516435894 -0.07051141852 0.000618
+0.002668717944 -0.07614078684 0.00062
+0.03415153341 0.01940009291 -0.015576
+0.04348532589 0.03033536303 -0.023334
+0.03206087588 0.02954430732 -0.020264
+0.06003734747 -0.01974922751 0.00062
+0.06182376261 -0.01611616839 -0.00366
+0.06266721136 -0.02001259667 -0.00538
+0.03266599579 -0.06140708857 -0.002228
+0.2317785459 0.5778461038 -0.01026
+0.2570237023 -0.6663024062 0.00062
+0.3382572249 0.6139125518 -0.044878
+0.325741042 0.6245470394 -0.02074
+0.3182015869 0.6106744784 -0.02218
+0.2542933845 0.6878830504 -0.005078
+0.2451356088 0.6853079299 -0.003586
+0.249611948 0.6783831276 -0.004978
+0.04777116719 -0.07546237629 0.00062
+0.04965388918 -0.07170457049 -0.003212
+0.02854129553 -0.02510941537 -0.00303
+0.2367497935 0.5678385743 -0.009488
+0.1284875397 -0.04554579814 -0.02089
+0.1408020027 -0.04360518925 -0.030804
+0.5182680636 0.04887158585 -0.544212
+0.5578700458 0.1312397554 -0.565404
+0.4809954849 0.1165012668 -0.561626
+0.7000766373 0.0559125305 -0.378324
+0.6606650763 0.06630667833 -0.490482
+0.6968913783 0.09342680939 -0.477596
+-0.2628125597 -0.03903066068 -0.025898
+0.005524514955 0.006546033643 -0.00779
+-0.1716499485 -0.6130490771 -0.038198
+-0.1596070879 -0.6251354718 -0.033752
+0.2939739812 -0.5711842176 -0.003072
+0.2873982686 -0.5659948519 -0.003372
+0.04600510172 -0.1027856026 -0.00028
+0.04493871849 -0.1041200369 0.00062
+0.2510091923 0.007437610662 -0.005586
+0.1068920943 0.03441829343 -0.037258
+-0.0493538971 -0.02370562841 -0.011346
+-0.03954951976 -0.02850595137 -0.011982
+0.1552863603 0.03995905979 0.00022
+0.1553312347 0.0414914369 0.00032
+0.1543833935 0.04105696109 0.00022
+-0.08274932568 0.2064647847 -0.00338
+-0.0830914154 0.1967067938 -0.004708
+-0.07386358455 0.1987197849 -0.00338
+0.3064826375 0.04507531382 -0.01613
+0.3139343386 0.04275930165 -0.060734
+0.1433547696 0.04970102114 -0.00303
+0.03263320282 -0.04124548516 0.000616
+0.03194568584 -0.04225751054 -0.00138
+0.03106033085 -0.04120277736 0.00062
+0.2831521842 -0.02404545626 -0.159432
+0.2942219328 -0.01891937659 -0.114918
+0.2951641655 -0.03351095454 -0.214838
+-0.3793160056 0.5413680813 -0.015564
+-0.3988284607 0.5468874627 -0.019008
+-0.3952463259 0.5241782523 -0.019212
+0.2300698843 -0.4414540262 -0.009418
+0.2229656492 -0.4331196152 -0.005294
+0.1402971495 0.04177482251 -0.01241
+0.1147952633 0.1579581019 -0.004512
+0.1210573379 0.148963199 -0.003912
+0.3387227922 -0.6332645813 -0.014084
+0.3501594835 -0.6184720512 -0.013468
+0.2623607949 0.7603643821 -0.00843
+0.321220634 -0.5908439218 -0.007922
+0.3143838817 -0.5855845079 -0.00528
+0.3122005294 -0.5914597587 0.00062
+0.007330012981 0.8423867841 -0.008906
+0.03738486184 0.8387810961 -0.002262
+0.03327736091 0.834903773 -0.001738
+0.225402017 -0.7334627542 -0.002482
+0.2084703923 -0.7455749043 0.00062
+0.213361261 -0.735572452 0.000612
+-0.4053278558 0.5354199195 -0.025292
+-0.4126294849 0.5504865899 -0.022962
+-0.4223753922 0.5329957622 -0.038372
+0.2948221794 0.3564746343 -0.005654
+0.2965239677 0.3663853864 -0.009228
+0.3012980817 0.3600516223 -0.01059
+0.01509758794 -0.07262770588 0.000616
+0.3139830679 -0.6343039665 -0.00277
+0.3105495404 -0.6332721172 -0.001218
+0.1757541862 0.008476926208 -0.003516
+0.177525518 0.005533382476 0.00062
+-0.1827301225 -0.4641098666 -0.010318
+0.06546055205 0.02053902921 -0.021776
+0.1185249759 0.02510248795 -0.036042
+0.1220988884 0.03001581752 -0.032598
+0.3337645332 0.1065840444 -0.036718
+0.3496480817 0.09104673334 -0.207812
+0.3441814156 0.1104356362 -0.100518
+0.2829864756 0.4677503143 -0.0169
+-0.1865791558 -0.7361594733 -0.027026
+0.07298030334 -0.07002357023 0.000608
+0.07439471982 -0.06727412283 0.00062
+0.05886460369 -0.07667347997 0.000618
+0.06050465646 0.08148048812 -0.025382
+0.05075713386 0.07496193061 -0.02375
+0.03270928039 -0.06302478053 0.000604
+0.08616298383 -0.07297749026 0.00062
+-0.1974783839 -0.0595650974 -0.013018
+0.0824689809 -0.05811361106 -0.008392
+0.2625342858 -0.5960528562 0.00062
+0.2586590095 -0.5967530589 0.000616
+0.261600823 -0.5974435313 0.00062
+-0.4223203434 -0.01449102761 -0.05368
+-0.4469754707 0.01572206587 -0.047978
+0.5626466996 -0.3653583163 -0.072556
+0.5312927459 -0.3435225144 -0.028582
+0.5402623612 -0.3642200372 -0.061922
+0.1971584401 -0.3293434159 -0.13906
+0.2133049845 -0.3329105781 -0.193224
+0.08836576777 -0.05680353124 0.000616
+0.08933369098 -0.05822349057 0.000618
+-0.2291016266 0.3512877605 -0.00544
+-0.2188025862 0.3429933978 0.00062
+-0.2331159596 0.3387744432 -0.002558
+0.02514357164 -0.006629554242 0.00062
+-0.0409388026 0.2123186916 -0.006284
+-0.04415657106 0.2194267596 -0.005178
+0.1057449602 -0.1080897613 -0.001472
+0.4248804953 0.08900914635 -0.399552
+0.4160716638 0.07361792105 -0.417538
+0.4120878508 -0.03951307487 -0.507078
+0.4240465556 -0.06174366795 -0.543852
+0.4535215488 -0.05679220276 -0.53455
+0.4389685022 0.2169185384 -0.305578
+0.4272725539 0.2350765056 -0.254772
+0.4517169477 0.2310685652 -0.36523
+-0.1660187684 0.7705317244 0.000518
+-0.1621219552 0.7707501623 0.000302
+-0.1620798937 0.7752167036 0.00022
+0.371833564 0.01526202076 -0.490092
+0.3834873817 0.01243636403 -0.512986
+0.2446064942 -0.04924966924 -0.220452
+0.2617106585 -0.039906888 -0.171272
+0.255467207 -0.4270016398 -0.01982
+0.3296520998 0.1224198875 -0.022458
+0.3359216224 0.1161999138 -0.039198
+-0.06231647246 0.8016474975 -0.003498
+-0.0586456632 0.8080796014 -0.006034
+0.01936866816 -0.03434370312 -0.003064
+0.01796637508 -0.03450639542 0.000616
+-0.2703786298 0.4531550584 -0.009894
+-0.2728745161 0.4662837532 -0.009834
+-0.2952449628 0.4524632715 -0.012918
+0.05847963672 -0.07751875562 -0.002276
+0.05763707052 -0.07677608631 0.000594
+0.1001694996 -0.03613867776 -0.002138
+0.09953934661 -0.03669248901 0.00062
+-0.1525066392 -0.006637348068 -0.013778
+-0.1693313717 -0.01361632526 -0.013286
+-0.4318499761 0.2962118839 -0.03165
+-0.4105939706 0.3126827764 -0.034132
+-0.3912660761 0.2988468346 -0.028406
+0.2991610082 0.6978847338 0.00062
+0.2814127984 0.6912089003 0.000612
+0.2946982594 0.6818656957 0.00061
+-0.08703462907 0.7939825195 0.000264
+-0.1440366557 -0.6777777892 -0.037318
+0.2444540534 -0.7018198698 -0.002902
+0.2451442639 -0.6933213084 -0.001464
+0.2318148985 -0.6973692961 0.00062
+0.04317720082 -0.09604833408 -0.001094
+-0.50221174 -0.02707906626 -0.090054
+-0.4793956556 -0.04431159584 -0.073774
+0.08492061564 -0.06026186231 0.00062
+0.07708256352 -0.06212708244 0.000618
+0.0814538802 -0.05925197711 0.00062
+0.1196298014 -0.08431732703 -0.00705
+0.1282421491 -0.09254986386 -0.007992
+0.3300213186 0.4979852954 -0.08601
+0.3090810915 0.4981950473 -0.090078
+0.5250217573 -0.08031281725 -0.244178
+0.1287738774 -0.01361474912 -0.05206
+0.1383486364 -0.01413424778 -0.022334
+0.3344441754 0.5235064183 -0.093996
+-0.04153848467 0.205538552 -0.007482
+0.3180171389 -0.6345564079 -0.005468
+0.435493268 -0.5162470658 -0.072822
+0.4150761905 -0.508706485 -0.027144
+0.4273352168 -0.492477235 -0.073986
+0.2515545636 0.773598994 -0.005262
+0.3295355184 -0.09689634994 -0.528558
+0.3371414769 -0.151328605 -0.5132
+-0.1872984224 -0.3966451216 -0.011092
+0.2368137211 0.7919592391 0.00062
+-0.3608201415 0.449907521 -0.020272
+0.08886124161 0.1982601322 -0.009716
+-0.2178323325 -0.3780901409 -0.02462
+-0.2163744382 -0.3940603463 -0.024168
+-0.01116841454 0.003325717289 0.00062
+-0.4363505311 0.1476161581 -0.029884
+0.04961188119 -0.0734804002 -0.00434
+0.05044042843 -0.07420577191 0.00062
+0.05068228449 -0.07240712381 -0.003794
+-0.2026833937 -0.270484975 -0.010386
+-0.1964898065 -0.2785558098 -0.009496
+0.02012823305 0.8192010883 0.000608
+0.02660848694 0.8171943971 0.00062
+0.01692943555 0.8190104007 0.00062
+0.0315714075 -0.08227201361 0.00062
+0.06651437726 -0.0745744192 -0.004774
+0.06667188857 -0.07737041453 0.000618
+0.06411700956 -0.07641167649 -0.004732
+0.03916204676 0.05294704075 -0.02802
+0.0008948818044 0.2362538381 -0.004338
+0.07250409253 -0.05874697748 0.000608
+0.0732442611 -0.06067640536 0.000592
+0.2801028729 0.4335209811 0.00062
+0.2809926246 0.4390183342 -0.003594
+0.2772243182 0.4476924296 -0.004942
+-0.1102181555 -0.05282710076 -0.009734
+0.3622918791 -0.599031486 -0.014066
+0.3746013548 -0.5986133703 -0.015506
+0.3777191476 -0.5876506296 -0.016038
+0.3431361468 0.4322885088 -0.115836
+0.2849455311 -0.5896678496 0.00062
+0.2894096907 -0.588177215 0.00062
+-0.6159789299 0.1757346397 -0.271526
+-0.6288331584 0.1343132241 -0.275516
+-0.585718329 0.1354748585 -0.209662
+0.1330043407 0.09173598624 -0.00573
+0.1420032785 0.04499262188 -0.00855
+0.1406788245 0.04818895955 -0.010086
+0.1350104576 0.0421099049 -0.02034
+0.585114484 -0.3274799029 -0.054758
+0.5671459165 -0.3258391699 -0.032522
+0.5752608366 -0.3453204423 -0.054884
+-0.3969552317 -0.01636033492 -0.055492
+0.02262220335 0.8331219878 -0.003464
+0.01709060675 0.8304913711 -0.003864
+0.01541435284 0.8337734054 -0.00509
+-0.2369774005 -0.3006543141 -0.022586
+0.03252881765 -0.04530595021 -0.002896
+-0.02421251867 0.2156847014 -0.00637
+0.2732767834 -0.6501644606 0.00062
+-0.233326515 -0.1710255961 -0.005224
+0.01445051275 0.8270191623 -0.003278
+0.01093822853 0.8226659053 -0.001524
+0.008202880484 0.8292909992 -0.003836
+-0.003001213513 -0.047505673 0.000608
+-0.005334099265 -0.04630585192 -0.002844
+-0.01729888257 -0.0915784437 0.000616
+0.06099327929 -0.08025163129 0.00062
+0.06012518409 -0.08338810354 -0.003372
+0.05916871065 -0.08303123035 -0.003246
+0.5737836958 -0.2448696953 -0.046258
+0.4441427334 -0.3698548793 -0.08538
+0.2060868912 -0.5507176589 -0.003008
+0.2016478726 -0.5323979976 -0.003216
+0.3997446288 -0.5773513585 -0.02213
+-0.09406728883 0.01395988437 -0.013658
+-0.102162658 0.02930729542 -0.014004
+-0.1126709616 0.0217492678 -0.013286
+0.2021274642 -0.1738402642 -0.028816
+0.194795515 -0.1854878231 -0.02156
+0.4084784185 -0.1943565434 -0.298826
+0.4469993159 -0.1647718661 -0.248848
+0.4181922883 -0.1680887559 -0.337462
+0.4537321859 -0.498425553 -0.101536
+0.4806294855 -0.502044254 -0.110952
+0.2250793034 -0.343027962 -0.142604
+0.08456686408 -0.0582704925 0.00059
+0.08459412847 -0.05908725864 -0.007638
+0.03660729786 -0.104637385 -0.000138
+0.03594151797 -0.1061872146 0.00062
+0.8270754437 0.1103309094 -0.231416
+0.6880753334 0.2732665189 -0.564516
+0.7514907159 0.1883259483 -0.462576
+0.2156185449 -0.4091206075 -0.005236
+0.2142466547 -0.3984187006 -0.006126
+0.2063043092 -0.4070139451 0.00062
+0.1188530856 -0.01321357584 -0.06172
+0.3110650229 -0.2356796499 -0.437028
+0.3313341677 -0.2544835435 -0.357444
+0.3044154885 -0.2629105136 -0.39699
+-0.1790018391 -0.06959665178 0.00062
+0.5013380839 0.2453154785 -0.529682
+0.07219731001 -0.05341388861 0.00062
+0.07402204323 -0.05533343807 0.000596
+0.07720903647 -0.05339161468 0.00062
+-0.0449358483 -0.1518730112 -0.002168
+-0.06144717464 -0.1503863601 -0.002336
+-0.046581123 -0.1432294854 -0.003294
+0.5265127862 -0.2326113893 -0.032514
+-0.1030978012 -0.6475384629 0.000538
+-0.10285726 -0.6583243233 0.00062
+-0.1003395864 -0.6711304132 0.00034
+-0.1540379677 -0.3846905999 0.000618
+-0.1593020866 -0.3802405071 -0.003418
+-0.1527664961 -0.3727863598 0.00062
+-0.475450362 0.04349828899 -0.067114
+0.5713750141 -0.1214029121 -0.11933
+-0.2299236368 -0.2223438388 0.00062
+-0.2386241174 -0.2175352863 -0.008612
+-0.1606364805 0.7731315223 -0.000856
+-0.1557599136 0.7690175052 0.00062
+-0.2736027624 0.4907284588 -0.0083
+-0.268374568 0.4819456254 -0.00716
+-0.2596697174 0.4810238212 0.000612
+0.1963486273 -0.1373425668 -0.028296
+0.2021794072 -0.1511004643 -0.029152
+0.3291719056 0.6468961422 -0.018728
+0.3444920616 -0.5306272864 -0.015862
+0.1186808206 -0.1133944787 0.000604
+0.2862238956 0.4478316989 -0.011108
+0.02670125299 0.8430342195 -0.005358
+0.02885917511 0.8359902793 -0.003344
+0.4629483622 0.1385972333 -0.535684
+0.4670440581 0.1627775158 -0.526444
+0.6971677479 0.1401222725 -0.485448
+0.4578619794 -0.1380229731 -0.283064
+0.06267571673 -0.07704126776 -0.002578
+0.06319048463 -0.07921904737 -0.003356
+-0.008670414345 0.9146906408 -0.14871
+-0.05194923775 0.8793921337 -0.04938
+0.3122737782 -0.6468510657 -0.007336
+-0.1556325921 0.04794769827 -0.014658
+-0.1432049945 0.05883848984 -0.015936
+0.464718883 0.338479533 -0.419576
+-0.01979793594 -0.008977524021 -0.00172
+0.4501938649 -0.002412551525 -0.523708
+0.4604472864 -0.02795002138 -0.548538
+0.4930490713 -0.02752491774 -0.5379
+-0.1757093916 -0.08718651109 -0.001116
+0.05090460454 -0.08283902919 0.00062
+0.03559953549 -0.0290755744 0.00062
+0.1555238519 0.03808365392 0.00042
+0.1542653142 0.039349226 0.00032
+0.2880595015 -0.5262068424 -0.010246
+0.3887523699 0.4478449585 -0.347786
+0.3970096687 0.4824760075 -0.37618
+0.4187834983 0.4509315045 -0.357132
+0.5390678975 -0.2675220902 -0.018592
+0.5338483158 -0.2842857511 -0.016314
+-0.2216256402 -0.1319187601 0.000354
+0.2529456073 -0.549451734 -0.004212
+0.2416008201 -0.5486844368 -0.004654
+0.2432471663 -0.5627680627 -0.00408
+0.1795041115 -0.1321736357 -0.013954
+0.003157754853 0.9001019267 -0.042964
+-0.01296577162 0.9012453076 -0.130244
+0.1964673474 -0.5129356439 -0.002816
+-0.07165418948 0.8364894649 -0.02981
+0.3348914437 0.2751311332 -0.044896
+0.3218662202 0.2662958861 -0.030762
+-0.09780567366 -0.03452774393 -0.010428
+-0.1010371312 -0.04430452977 -0.010206
+-0.03155191654 -0.02306282056 -0.009928
+-0.02418824836 -0.02498783869 0.0006
+-0.02359970482 -0.02332975123 0.00062
+0.2206457419 -0.444234732 -0.00412
+0.2197408112 -0.4522207806 -0.005022
+0.2269568171 -0.4501215168 -0.006918
+0.3504018593 0.2253935833 -0.059044
+0.3354439552 0.2182608517 -0.029968
+0.1740999845 -0.03057052166 -0.030228
+0.1779654131 -0.0215904336 -0.013606
+-0.2437362553 0.4445349176 -0.005846
+0.3222780871 0.139937154 -0.004628
+0.3153740065 0.1421196259 0.00062
+0.04374956724 -0.04612546655 -0.00338
+0.0446204891 -0.04690243902 -0.00338
+0.2664882635 -0.01416367939 -0.014946
+0.2706125028 -0.02553717131 -0.077908
+0.3023510502 -0.5516545372 -0.009306
+0.05539376867 -0.06549362771 -0.000576
+0.05503651736 -0.06898301933 -0.000612
+-0.03342847128 0.8455426963 -0.014798
+-0.02259476634 0.8537247261 -0.01938
+0.3015691866 0.6907758775 0.00062
+0.296473641 0.682388579 0.000614
+-0.01436270997 0.8210035055 -0.002958
+-0.004861309295 0.8234325945 -0.002566
+-0.2389054217 -0.2015981081 -0.007558
+0.08008408479 -0.05892085984 0.0006
+-0.1172977811 0.8281374926 -0.016748
+-0.1341447518 -0.5314317736 0.000468
+-0.6128828302 0.09545910036 -0.22154
+-0.6665844985 0.1077154052 -0.227536
+-0.3277796981 -0.2045201418 -0.043708
+0.06066022201 -0.02154414373 -0.002776
+0.1891603703 -0.3382141122 -0.006986
+0.2016066701 -0.345020427 -0.073708
+0.4869358084 -0.2801694751 -0.026338
+0.4896404222 -0.2958282484 -0.027488
+0.499765798 -0.286130072 -0.021124
+0.08095023724 -0.02329993228 0.000608
+0.07939933038 -0.05025769779 0.000618
+0.08033392448 -0.0471900004 0.00062
+0.07062600524 -0.08156226192 0.00062
+0.08991080497 -0.08293308693 0.00062
+-0.1779060239 -0.3232920261 -0.00686
+0.1853514329 -0.003186101336 -0.002532
+0.1890214239 -0.004222078459 0.000612
+0.4530332607 -0.2834454294 -0.067332
+0.4696490765 -0.2718582694 -0.045294
+0.4722778182 -0.2902541373 -0.038098
+0.123090839 -0.0240995479 -0.053294
+0.1209043914 -0.03694541077 -0.029612
+-0.3026323406 0.18854692 -0.023508
+-0.3145046614 0.136861976 -0.024674
+0.5288379238 0.2691045585 -0.570584
+0.1928062661 0.5753835596 -0.003922
+0.1850104415 0.5791788622 0.000524
+0.1846964577 0.567844171 0.00062
+0.2149731096 -0.4184509133 -0.004224
+0.2073823664 -0.4221467902 0.00062
+-0.1652199316 -0.6783678866 -0.04235
+0.0336624309 -0.07641683195 -0.00447
+0.003725143568 -0.05287448922 0.00062
+0.3485773347 0.2850321612 -0.066888
+0.0313289022 -0.04413830156 -0.003702
+0.03161610754 -0.04291116286 -0.00204
+-0.289609526 0.5403315441 -0.002262
+-0.1925230056 -0.2866310785 -0.009342
+0.1899133175 -0.05233977201 -0.039212
+0.1953642768 -0.0426837419 -0.023746
+0.09313227767 -0.06538281336 -0.000894
+0.3050249956 0.3811305825 -0.030134
+0.3458541277 0.1773542581 -0.05866
+0.05655014734 -0.06713282933 0.00062
+-0.1760831728 -0.5564191439 -0.026188
+-0.1871138967 -0.5515780814 -0.029772
+0.05519339809 -0.01473718434 0.00062
+0.3289995967 0.5991979006 -0.034184
+0.6152479765 -0.363161468 -0.086054
+0.597499928 -0.3427759602 -0.06921
+0.5725391331 -0.387188866 -0.086152
+-0.149790627 0.7739857439 2e-05
+-0.1495909952 0.7771271659 -0.001074
+-0.02569720667 -0.1258079769 0.000616
+-0.3647584671 0.4064077615 -0.02514
+-0.3837937378 0.403757017 -0.027494
+0.3220817973 -0.6306546959 -0.00859
+0.3245603514 -0.62589245 -0.007766
+0.329222287 -0.6318146238 -0.01236
+0.2378344685 -0.5443058368 -0.00512
+0.2310767234 -0.530723574 -0.005878
+-0.1862928118 -0.05331236898 -0.010604
+0.08136909925 -0.05052198632 -0.00877
+0.07876851263 -0.05159555798 -0.002754
+0.1696980654 -0.1094690811 -0.016392
+0.1454787488 0.05426683674 0.000618
+0.1491311663 0.06094923414 0.000616
+0.1440414523 0.05866360769 -0.005242
+-0.1537137175 0.2120421051 -0.00294
+-0.1504296036 0.2017017484 -0.004428
+0.8014329525 -0.2072939041 -0.098514
+0.2468185465 0.7792025613 0.00062
+0.3400708526 -0.5913304685 -0.014162
+0.3486790583 -0.5867889164 -0.01374
+0.3391858369 -0.5813682935 -0.014076
+-0.4969706256 0.2758702922 -0.13864
+0.5141771659 -0.2840170857 -0.01724
+0.01883871419 0.2034250174 -0.010818
+0.240760752 -0.251552279 -0.277314
+0.03566737893 0.815876286 0.00062
+0.1883920572 0.6281042705 0.00059
+0.1838345389 0.6193360721 0.00062
+-0.4538888514 -0.04542565299 -0.05458
+-0.4320157281 -0.03571627467 -0.05015
+-0.03651088014 -0.1519213819 -0.001974
+-0.03290136563 -0.1597628199 -0.000526
+-0.0294362954 -0.1511692297 -0.001416
+-0.1266379441 0.8061059751 -0.004282
+0.09174043649 -0.05352188375 -0.000782
+0.09225073836 -0.05517920661 0.00062
+0.2031403253 -0.5669131844 0.00062
+0.217819146 -0.7262845626 0.00062
+0.2465369154 -0.6071837534 0.000366
+0.2471745912 -0.610390446 -0.000626
+0.3057302082 -0.6303853926 0.000618
+0.3076672418 -0.6316492487 0.000618
+-0.1623145608 -0.3212687889 0.000586
+-0.1576291812 -0.3498638102 0.00041
+-0.1604017369 -0.3396392647 0.000538
+0.09554411351 -0.04028207014 -0.00172
+0.1552790724 0.03653043614 0.00052
+0.2517787027 0.01362801226 0.000616
+0.2554181674 0.009430430095 0.000616
+-0.5500045808 -0.1619451018 -0.163276
+0.259313404 -0.5710121414 -0.00418
+0.2843172273 -0.5574319199 -0.003826
+0.05008345281 0.1831126616 -0.01702
+0.03707610808 0.1967996076 -0.013308
+0.04616184116 0.1935139958 -0.014378
+0.3530113733 -0.03094930404 -0.438394
+0.2281750221 -0.3314313425 -0.245734
+-0.2544992607 0.2415050661 0.000618
+-0.2593263695 0.23597869 -0.005696
+0.9017082538 -0.1200591516 -0.098144
+0.08913142535 -0.04097359521 -0.004088
+0.6010284479 0.04106206342 -0.500816
+0.5690073366 0.05681003781 -0.49067
+0.3940694907 0.1428125426 -0.252412
+-0.2681639354 -0.1295580702 -0.020876
+-0.01098412269 -0.02809321486 0.00062
+-0.01314717131 -0.02892777088 -0.000112
+-0.01194518003 -0.03035462282 0.00062
+-0.06433680053 -0.135379333 -0.005008
+0.1729807412 -0.1557515563 0.00062
+0.1525819826 -0.1354843872 0.00062
+-0.3942392575 0.04901334922 -0.048002
+-0.3704351506 -0.4264370656 -0.107268
+-0.3652641252 -0.3797869801 -0.096058
+0.03957519154 -0.03643725657 -0.002192
+0.03829147244 -0.0346441126 -0.002996
+-0.4992859886 0.06491456398 -0.136728
+-0.4967241351 0.02900227909 -0.091292
+-0.2228523583 0.3600472247 -0.004368
+0.8131019943 -0.04564809975 -0.059278
+0.02706781148 -0.06806133526 0.00062
+0.02649380624 -0.06477042266 0.00062
+0.03056675957 -0.06517503786 -0.003946
+0.2119027237 -0.449830118 0.00062
+0.2153780151 -0.4586652893 -0.003696
+0.3579753629 -0.3744488917 -0.132822
+-0.2536347434 -0.151103494 -0.010912
+0.733299727 -0.1757353539 -0.048364
+0.7587990543 -0.1568675274 -0.05316
+-0.1552655819 -0.3933617121 0.000566
+-0.1565991904 -0.4049184711 0.00062
+-0.1409737934 0.7731293404 0.00042
+-0.1731398922 -0.3117368356 -0.005492
+-0.1444104335 0.7777125187 0.00062
+0.08460246594 -0.01167132851 -0.004516
+0.04251178913 -0.08380362751 0.000614
+-0.3613888133 0.0476316016 -0.037576
+-0.3644021759 0.02725633323 -0.042634
+-0.1359327533 0.7736018241 0.00062
+-0.1061452287 0.7871530219 0.00062
+0.2013927653 -0.2392396375 -0.014928
+0.1942543231 -0.2471768966 -0.007568
+-0.102002558 0.7870415447 0.000454
+0.1826041048 -0.1613167476 -0.016144
+0.1885245228 -0.1487130062 -0.025562
+0.7805480363 0.1502876226 -0.458696
+0.7992181438 0.1221348603 -0.335854
+-0.03408268748 0.8033880798 0.00062
+0.2121909084 -0.4393598665 0.00062
+0.1899790617 -0.2400341661 -0.003558
+-0.3716886323 0.5171014517 -0.01605
+-0.3795366873 0.486746321 -0.019364
+-0.09230463927 0.2091177478 -0.00338
+0.1551514049 -0.1193338973 -0.00638
+0.1608814221 -0.1100751511 -0.013582
+-0.1648458054 0.786586137 -0.002678
+-0.168077084 0.7793152273 0.00052
+0.1248617048 0.07880810222 0.000592
+0.7900288518 -0.120318246 -0.049858
+0.7840140605 -0.1006550288 -0.051044
+0.8145367376 -0.1131186646 -0.05464
+-0.2539079306 0.06740160782 -0.023082
+-0.2565129996 0.2524693996 0.00044
+-0.2280696221 0.4089944694 -0.005282
+-0.2125902981 -0.711198384 -0.10574
+-0.2291667482 -0.7152405898 -0.160502
+0.2651757677 -0.6582639053 0.000598
+0.1431484593 0.02167300795 -0.013544
+0.1368078194 0.02038571848 -0.026426
+0.06571572884 -0.03755245679 -0.003702
+0.06617686326 -0.03600893719 0.000616
+0.1931338513 0.636924945 0.000444
+0.8382292198 -0.1733010002 -0.097626
+0.2527340792 -0.6074378819 0.00062
+0.260764421 -0.6078433726 0.00062
+0.2587566477 -0.6045294643 0.00062
+-0.08966554396 0.1901642567 -0.004434
+-0.07677091764 0.1880417621 -0.005514
+-0.08522784944 0.1794961193 -0.00547
+-0.4516102586 0.2790617102 -0.03415
+0.1545507107 0.03794457735 0.00052
+0.1535499523 0.03651706136 0.00052
+0.04155667004 -0.08475265365 -0.001606
+0.04064456033 -0.08575273437 -0.00184
+-0.4447208425 -0.2502640702 -0.120778
+0.6068401718 0.01120663324 -0.388576
+-0.3894718375 0.5041007187 -0.018892
+0.2016445226 -0.2289977252 -0.016588
+0.194796484 -0.235234653 -0.00941
+-0.3019144117 -0.3216764399 -0.042104
+0.3312238164 0.09665496847 -0.074268
+0.004151204857 0.06326893133 -0.024708
+0.02472804719 0.04994683903 -0.028114
+0.3910867077 0.3806908895 -0.352666
+0.09338671485 -0.05130849266 0.00062
+0.09281804688 -0.05036549008 -0.007956
+0.2595162024 -0.4385705317 -0.019948
+0.2601134395 -0.4498387857 -0.017252
+0.1013379212 -0.03675535838 -0.006026
+-0.2370986158 0.4144260615 -0.00617
+-0.2381210593 0.4252012779 -0.005604
+-0.2576487385 0.4288139071 -0.00938
+0.1888660106 -0.2315123501 -0.0046
+0.3128505612 0.1479537502 0.00062
+-0.2075574829 0.1946539659 -0.010232
+-0.1985585198 0.1951801967 -0.009734
+-0.2049085899 0.2040567376 -0.00521
+0.6507281245 -0.09746431959 -0.077462
+0.639957282 -0.06923928102 -0.091328
+0.6256871691 -0.09390398339 -0.086624
+0.02125415262 -0.01458231887 -0.017438
+0.0228202591 -0.01251618517 0.000598
+0.3455804126 0.1661168654 -0.05897
+0.621498155 -0.2263097201 -0.072874
+0.6678013665 -0.2155294996 -0.068314
+0.3635633812 0.04014243839 -0.42494
+0.3576764018 0.04826440922 -0.395014
+0.3529127911 0.041694825 -0.342148
+0.0696631938 -0.05848926178 0.00062
+0.0684567715 -0.0528658568 0.00062
+0.07237775006 -0.0570279528 0.000618
+0.3295013959 -0.5742430695 -0.013114
+0.3301766202 -0.5857006088 -0.012906
+0.2602486207 0.7916819676 -0.005284
+0.2516143131 0.8043962756 0.00062
+0.2808125987 0.7685173509 -0.00829
+-0.05334205809 0.006179282364 -0.012688
+-0.1551681275 -0.05417172355 -0.009812
+-0.160712962 -0.05915889739 -0.006446
+-0.1512086524 -0.06139591199 -0.004768
+0.3331920151 0.656358648 -0.02158
+-0.1086715266 -0.6902093206 -0.004062
+0.03363001255 -0.03432081206 0.00062
+0.03198638687 -0.03367015361 0.000618
+0.03419176395 -0.03211056159 0.00062
+0.5135705938 -0.2476709195 -0.023122
+0.5338864961 -0.2518215636 -0.016894
+-0.8932913531 -0.02592003909 -0.137608
+-0.8655890375 -0.04838173439 -0.122786
+-0.224999275 -0.4237575743 -0.025502
+0.0259679016 -0.04272360527 0.00062
+0.4565147637 -0.212341388 -0.147198
+0.4259652777 -0.2193976503 -0.201106
+0.09604522079 -0.03983542811 -0.003126
+-0.02352896795 -0.1133232962 -0.003734
+-0.6254275516 0.3893476142 -0.310434
+-0.5109936863 0.4758164744 -0.256578
+-0.5315631288 0.3915432767 -0.275144
+0.3293400052 0.3768384672 -0.202248
+0.3161170273 0.3898413692 -0.08461
+-0.2376286494 -0.162752581 -0.009092
+-0.2476207631 -0.1605657109 -0.00938
+-0.1724456667 0.7791173402 0.00062
+-0.1882209554 0.7668772109 0.00058
+0.57986535 -0.4358030091 -0.09112
+0.04875435811 -0.1011083345 0.000216
+0.04695852038 -0.1018370278 0.000618
+0.08307390259 -0.02846975074 -0.005442
+0.08301348129 -0.02551259439 -0.00538
+0.04382570457 -0.05876123878 0.000618
+-0.09873462226 0.8251999918 -0.01298
+-0.09340563722 0.8150676881 -0.009204
+-0.154865546 -0.3600687205 0.000606
+-0.163765152 -0.3719129008 -0.005238
+0.3691813174 0.4667117054 -0.305308
+-0.3622529013 0.6066622466 -0.007408
+-0.3647623525 0.6188399258 -0.00637
+-0.1226373095 -0.02938555943 -0.010126
+0.03648179347 0.8185397562 0.00062
+0.057303457 0.8604031087 -0.002376
+-0.1659259071 0.7763468203 0.00062
+-0.2354930657 -0.2591313891 -0.01938
+-0.230999327 -0.2492053775 -0.015154
+0.2062834402 -0.1627714643 -0.031618
+0.2161403157 -0.1712422477 -0.022096
+0.006880853153 -0.03047703672 0.000608
+-0.2118564103 0.2112396693 0.000618
+-0.6569394377 -0.1848002087 -0.150526
+-0.119789404 0.2139967692 -0.00338
+-0.1132047958 0.2018212786 -0.00338
+-0.1277067 0.2039464813 -0.00338
+0.04534546239 0.01572303424 -0.016046
+-0.2507979333 0.3504734452 -0.012092
+0.2522236804 0.699913401 0.00062
+0.2651923102 0.7353117627 0.00062
+0.7479242014 -0.1368845099 -0.049144
+0.7495229111 -0.1186337593 -0.041958
+0.7668213942 -0.1318803933 -0.047352
+0.4016790247 0.3621350013 -0.359544
+0.09035064115 -0.008332833742 0.00062
+0.3221079564 0.04033941949 -0.124272
+0.3247202633 0.02994132204 -0.102434
+0.3152495671 0.03396722975 -0.082214
+0.316305711 0.3155644979 -0.021176
+0.07138850816 -0.06054991566 -0.004002
+-0.1714969177 -0.1135812016 -0.003852
+-0.1662683 -0.120158484 -0.003112
+0.312688499 0.1992964601 -0.006252
+0.3023005952 0.2015219058 0.00062
+0.3054910749 0.1921306788 0.00062
+-0.02145431862 -0.04104566827 -0.005428
+-0.5409120838 0.2949504844 -0.276378
+-0.5079955577 0.3114833387 -0.254306
+-0.09017661288 -0.1087876151 -0.005936
+-0.1114126388 0.1767016592 -0.003388
+0.435841532 0.1989464366 -0.334478
+0.4547349431 0.205232685 -0.415534
+-0.01875922045 0.005795927814 0.000614
+-0.02154718537 0.01305521257 0.000606
+-0.0293297431 0.004974867782 -0.017524
+0.2277209425 -0.5935857128 0.00062
+0.3469198592 -0.04266611424 -0.389054
+-0.03715769953 0.226796047 -0.00338
+-0.228438805 -0.1243333748 -0.010894
+0.2124070398 -0.5595239324 -0.00323
+-0.04072053178 0.04747412905 -0.017446
+-0.03357852947 0.03975384079 -0.013004
+-0.04358753109 0.03639552521 -0.014664
+-0.07342942666 -0.06032971124 -0.009014
+-0.01210661433 -0.01104022396 0.00062
+-0.01616979553 -0.01590998945 0.00062
+-0.01617485951 -0.01039906157 0.00061
+-0.1301012937 0.05811947098 -0.014906
+-0.13351098 0.06742309007 -0.01453
+0.3229046096 -0.28104901 -0.3437
+0.4821980096 -0.05251219022 -0.492514
+0.2984745619 0.4048805441 -0.015562
+0.2910417073 0.4129669457 -0.008794
+-0.2003136138 -0.3970560459 -0.018836
+0.1264652434 0.07049246314 -0.017706
+-0.2001451122 -0.2588616761 0.00062
+0.5925754669 -0.1417509559 -0.097296
+0.3520679957 -0.07214063756 -0.486952
+0.3516104171 -0.05634024286 -0.491068
+0.3338271898 0.3928556959 -0.214118
+0.3313588448 -0.5189025905 -0.0288
+0.3458075688 -0.5111954495 -0.016948
+-0.08792562561 0.02561018351 -0.014864
+-0.08261924681 0.01276422967 -0.014044
+0.2197812747 -0.5670682272 -0.002902
+-0.2472428836 0.3051606169 -0.00297
+0.09144540155 -0.05839846255 -0.00085
+0.09270078138 -0.05859430288 -0.000326
+0.09373130448 -0.05695233264 0.000618
+0.07064738977 -0.04240415964 0.00062
+0.3040169962 -0.6320938105 -0.001268
+0.3017129686 -0.6323769265 0.00062
+0.3026603732 -0.630272053 -0.001146
+-0.245668083 0.31406922 -0.004304
+-0.2563830369 0.3101286617 -0.011106
+0.2764488902 0.5873943757 -0.022772
+-0.2061558789 -0.06431437356 -0.01347
+-0.02752322949 -0.1562523721 0.00062
+0.0304505018 -0.05903315091 -0.005164
+0.03087921623 -0.05719285421 -0.00538
+0.02853515084 -0.05753859466 0.00062
+0.1841484649 -0.2212615407 -0.004614
+0.1828969194 -0.2094673064 -0.004536
+-0.2328712007 -0.1555985623 -0.006444
+-0.4533639806 0.3028438217 -0.106826
+-0.4762285145 0.2940904727 -0.168188
+-0.09023062017 0.1391238023 -0.014974
+0.03419535542 -0.05539241054 0.00062
+0.03200851979 -0.05566337972 0.00061
+0.3953273315 0.3411503813 -0.297286
+0.3720376603 0.3385600004 -0.12217
+-0.1688254109 -0.0827270243 -0.002344
+-0.176750824 -0.08078574959 -0.000706
+-0.1718774852 -0.07580212989 -0.000894
+0.02856704178 -0.07922687772 0.00022
+0.03255032543 -0.07796284911 0.00062
+-0.1368402167 -0.1022991497 -0.00538
+-0.0851175891 0.05703512053 -0.017442
+-0.08414662348 0.07779286928 -0.021006
+0.04956218898 -0.04939655868 0.00062
+-0.1692498173 0.05502879627 -0.017412
+-0.1682391159 0.09208571953 -0.015394
+-0.02422146638 0.2425616881 -0.002124
+0.2599128427 0.745032299 0.000618
+0.29886615 -0.05724081341 -0.395494
+0.3192731229 -0.08511532925 -0.507376
+0.003184885249 0.1894622154 -0.014976
+0.3571083317 0.6076908143 -0.140044
+0.3559413295 0.6269753431 -0.094376
+0.275120005 -0.5300145755 -0.005972
+-0.2408962404 -0.5609385248 -0.040906
+0.02470685032 -0.06395192722 0.00062
+0.2948459113 -0.6160143778 0.000618
+0.304135718 -0.5872536619 0.00062
+0.09164055162 -0.07299935895 0.000618
+-0.0154819251 -0.02955890842 0.00062
+-0.01787371139 -0.02959949817 -0.000318
+-0.2277204696 0.3355567271 0.00062
+-0.2334709636 0.32757302 0.000618
+0.1747316177 0.02106720791 0.00062
+-0.3520850317 0.6312326822 0.00062
+0.3854706956 -0.2407615477 -0.237748
+0.4080100911 -0.2369965271 -0.208174
+-0.1702013073 0.7650232052 0.00041
+-0.1694261721 0.7685721494 -7.4e-05
+-0.1731597104 0.768994395 0.000148
+0.08630896171 -0.05774072068 -0.002228
+0.08741019041 -0.05644418228 -0.001022
+0.08726591708 -0.0573173043 -0.00127
+0.2759977499 0.4980614678 -0.018086
+0.3018381602 0.2825918714 -0.012052
+0.31203549 0.2833322383 -0.020982
+0.3023876548 0.2726509015 -0.010734
+-0.188611478 -0.7036060273 -0.037346
+-0.1465923536 -0.07016360792 -0.004258
+-0.1512779102 -0.07795730109 -0.002866
+0.8509195625 -0.04084052209 -0.05952
+-0.2469185713 -0.6978731704 -0.16313
+-0.2253560807 -0.6936327536 -0.16276
+0.01595284108 0.8900049797 -0.02169
+0.02014528211 0.9029904319 -0.02407
+0.3783554512 -0.2671432622 -0.22168
+0.108550232 0.09731344682 -0.019756
+0.1019791124 0.1055686434 -0.01955
+-0.4663706318 0.1809744372 -0.034616
+0.08348850114 0.9673236277 0.000618
+0.07141622479 0.9056384362 0.000618
+-0.01654345677 -0.04033108909 0.000598
+-0.01363724561 -0.03933278749 0.00062
+-0.1717667184 -0.3575538934 -0.0069
+-0.1657381771 -0.3618633838 -0.005828
+-0.01746169467 -0.008869472515 0.000618
+-0.1286044358 -0.1051518063 -0.00383
+0.001827378598 0.8177601025 0.000542
+-0.2119481381 0.4154326272 0.000618
+-0.213753124 0.3936418887 -0.003222
+0.1488264469 -0.084907745 -0.014054
+0.09540378199 -0.07567214049 0.00062
+0.09320690479 -0.07669882993 0.000606
+0.3252855947 0.06670604978 -0.19144
+0.3232532239 0.06044608288 -0.212246
+0.3669060069 -0.5311109874 -0.017284
+0.3643049706 -0.5157958596 -0.016912
+0.3529919374 -0.5246725721 -0.01701
+0.688268901 -0.07503556707 -0.075986
+0.007602889425 -0.03944688663 0.000618
+-0.206116986 -0.6007835044 -0.042278
+-0.2068830198 -0.618600168 -0.050552
+-0.03017860098 -0.03018618336 -0.009514
+-0.02327365789 -0.02973653449 0.00062
+0.3222310332 0.2525255895 -0.027168
+-0.02752060588 -0.1629666568 0.00062
+0.289387778 0.6604724844 -0.00788
+-0.2853299398 -0.3238649643 -0.031064
+-0.2680507097 -0.3162386617 -0.025676
+-0.2776671054 -0.3064182581 -0.026754
+-0.182189883 -0.335381226 -0.007736
+0.01439471809 -0.05143876911 0.00062
+-0.3919559343 -0.6052260192 -0.18464
+0.2236063615 -0.390730705 -0.025504
+0.7513403138 -0.09983192534 -0.041042
+0.7385999443 -0.08026849125 -0.048458
+0.7686440508 -0.08558402395 -0.045514
+0.04204179595 -0.05402381555 -0.002744
+0.04104237776 -0.05257183568 0.00061
+0.296085166 -0.5604881377 -0.005638
+0.2400843443 0.6782656263 -0.003552
+0.2371885927 0.6885158007 0.00062
+0.2307769668 0.683225839 0.000596
+0.3436766499 -0.6113896276 -0.014172
+0.2891662643 -0.06321922538 -0.332418
+0.2902519206 -0.04853083956 -0.32808
+0.09751521325 -0.02167255379 0.000616
+-0.2241400932 0.1980375779 -0.011672
+0.3180503224 0.06344154338 -0.093704
+0.3111463565 0.05949718669 -0.018162
+0.06929742053 -0.07293634828 -0.004594
+0.03299456182 0.09505710002 -0.02495
+0.02432212396 0.08508792952 -0.024424
+0.280639881 -0.4090343925 -0.086416
+-0.1615760922 0.7836309283 -0.000556
+0.04780701073 -0.04730301922 -0.000874
+0.04977943872 -0.04704073327 0.000618
+0.09803833884 -0.03724916918 -0.002448
+0.1505739994 0.04568871234 0.000612
+-0.3830842662 0.5640729676 -0.014384
+0.3423491504 0.1561811342 -0.043254
+0.3541338935 0.1559188373 -0.180372
+0.4377136366 0.4856359788 -0.385964
+0.05589332392 -0.07026474313 -0.00138
+0.2541522508 0.7987899343 0.00062
+0.2276770814 -0.2189176395 -0.097662
+0.2128303321 -0.2078465936 -0.027174
+0.06714100284 -0.03349523392 -0.00537
+0.06977934234 -0.03534286872 0.00062
+0.04752061235 0.8924829194 -0.008848
+0.05866735284 0.8967921296 -0.005626
+0.05702606043 0.8868462659 -0.005574
+-0.2757882634 0.4383596059 -0.011616
+0.004660747984 0.8849843275 -0.030628
+-0.1433725188 -0.7278797891 -0.007902
+-0.1365169905 -0.7363626243 -0.006064
+-0.1320194669 -0.7231064734 -0.004902
+0.2145321277 -0.5017423707 -0.005524
+0.2124797304 -0.5120846507 -0.005598
+0.2227633875 -0.5090804538 -0.00738
+0.2943331491 0.02030715827 0.00062
+0.06866009575 -0.03714656135 -0.003728
+0.115780472 -0.07344064164 -0.010714
+-0.1622398099 -0.3107098382 0.00062
+-0.1681257798 -0.321495386 -0.00393
+-0.3504314972 -0.004500972428 -0.048312
+0.2536947652 0.6485351992 -0.009672
+0.2628758677 0.6561337769 -0.009726
+0.2536969648 0.6601010744 -0.006608
+0.08512370259 -0.05056882376 0.00062
+0.08663040694 -0.05368036159 0.00062
+0.08938869192 -0.05201321755 0.000618
+-0.1555097799 -0.4856481218 0.000618
+0.1879918579 -0.3060243614 0.00062
+-0.2115624874 -0.3271387341 -0.019974
+0.6462617297 -0.3200473354 -0.072648
+0.5632384934 0.1632549328 -0.572054
+0.2246639005 -0.07218812111 -0.021518
+0.228936915 -0.0556317435 -0.104626
+-0.0005314473284 -0.07704134973 -0.000656
+-0.138116535 -0.7786177548 -0.007476
+-0.130678725 -0.7773270498 -0.003598
+-0.3333175605 -0.3428440199 -0.043844
+0.2675888756 0.4943658011 -0.008952
+0.2600635195 0.5017608535 -0.006144
+0.05929215919 -0.06518049318 0.00062
+0.1471584811 -0.01557917046 0.000608
+0.1555687921 -0.02101763602 -0.000766
+0.1492702682 -0.00524465353 0.00062
+0.3866489128 0.2367480808 -0.205162
+0.3862933571 0.260845612 -0.21947
+0.2851001587 0.430468686 -0.002112
+0.2959771153 -0.6207843236 -0.001068
+0.2944803229 -0.6197864542 -0.000714
+-0.01862002974 0.2521772336 0.00062
+-0.325545066 -0.09074091016 -0.05047
+-0.2674408242 0.4611005706 -0.008974
+-0.1468296632 -0.03289020717 -0.010692
+0.3259652423 0.1796823614 -0.010598
+0.3340004419 0.1819982105 -0.018514
+0.3313485135 0.1926091447 -0.018898
+0.08714476549 -0.03256548636 0.000612
+0.08637851849 -0.03112220755 0.0006
+0.08462697039 -0.03373976907 -0.00616
+-0.3481425017 0.4290532109 -0.019252
+-0.349953034 0.4154256809 -0.020522
+-0.3620853889 0.4241654196 -0.02367
+0.1094553052 -0.05618541092 -0.016846
+-0.1466581712 -0.7584272707 -0.012428
+-0.1483916834 -0.7727190845 -0.01417
+-0.2801077354 0.481853942 -0.0103
+-0.291170626 0.4817633805 -0.01168
+0.3163187556 0.1904285252 -0.00605
+0.3121225658 0.1846344494 -0.00322
+0.05499064574 0.1921412133 -0.015132
+0.0694300389 0.1745428836 -0.017686
+0.07339059385 0.1847117081 -0.015512
+0.1811490113 0.01906779835 0.00062
+0.179472031 0.01688441424 -0.002898
+0.1785941207 0.02191317965 0.000618
+-0.1389688513 0.7723156725 0.00042
+-0.009340506441 0.1040905241 -0.022432
+0.02044819078 0.09691172655 -0.02222
+0.1135432413 -0.06474949901 -0.014362
+0.105875896 -0.07071330008 -0.007676
+0.2697355494 0.4777435439 -0.009006
+0.2676027794 0.4851842393 -0.006822
+0.08084285083 -0.04334983706 0.00062
+-0.3702584233 0.3814615559 -0.02642
+0.06512983014 -0.07292368837 0.00062
+0.06667141439 -0.07163086328 0.00062
+-0.1225523901 -0.7118959073 -0.004856
+0.2977194351 0.2929608775 -0.007022
+-0.2000670128 0.1349698454 -0.01679
+-0.1903220384 0.1436199246 -0.018244
+-0.1986184511 0.1518427777 -0.017012
+-0.3746788959 0.6117037642 -0.008564
+-0.4047153187 0.5787539084 -0.016656
+0.1223617697 0.01887946176 -0.04765
+-0.1947219253 -0.3148335571 -0.010828
+0.06010700515 -0.07789251962 -0.002598
+0.4035968489 -0.07374195035 -0.54454
+0.4183150039 -0.09038046863 -0.52646
+0.390754298 -0.09409212344 -0.530928
+-0.1094053547 0.005563189048 -0.013782
+-0.1155838046 0.0110102099 -0.013276
+-0.2232628927 -0.6037603103 -0.052532
+0.0001582246695 -0.07186518757 0.000614
+-0.1634400222 0.03556991459 -0.014736
+-0.1363397777 0.03863056295 -0.014114
+-0.1085586096 0.2136447792 -0.00338
+0.1445917868 0.008320509432 -0.01248
+0.36750348 0.08611060554 -0.24795
+0.3555751764 0.1034233389 -0.210234
+-0.1765717416 -0.288030335 0.000378
+0.05669411875 -0.06286618609 -0.000242
+0.147490754 -0.124194872 -0.002708
+0.1534249008 -0.1287023274 -0.001956
+0.413194845 -0.5798181829 -0.032488
+0.4296839473 -0.5655124668 -0.042466
+0.004167829668 -0.04137977848 -0.00412
+0.003639503868 -0.03866008076 -0.003948
+0.0005902959927 -0.04157556098 0.00062
+-0.00864174557 -0.07552060338 0.000618
+0.4064197633 0.06250531911 -0.403468
+-0.1220077112 0.01621962428 -0.013546
+0.1167560317 -0.04741598427 -0.020392
+0.003780327811 -0.02600362406 -0.00538
+-0.1509839375 0.1354958595 -0.017714
+-0.1596083361 0.1388279325 -0.016512
+-0.1597416611 0.1246558551 -0.017762
+0.001201681518 0.2272769489 -0.00538
+-0.007131082254 -0.06610179155 0.000614
+0.08094495797 -0.03273300078 -0.009164
+-0.5709678799 0.1731124127 -0.22898
+-0.3449857714 0.5366950744 -0.01379
+-0.3754016648 0.5713812613 -0.012812
+-0.1264340726 -0.8468416491 0.000618
+-0.1337909722 -0.8510752766 -0.004846
+0.2495328593 -0.4665450469 -0.011744
+0.2424077546 -0.4509035983 -0.010574
+0.2600861339 -0.4603594694 -0.014634
+0.4778684808 -0.162270258 -0.19328
+0.1316564657 0.03692640772 -0.02734
+0.1358347318 0.03133211227 -0.020822
+0.5721122008 -0.06862228833 -0.220632
+0.5750781182 -0.09293178464 -0.137068
+0.5538896573 -0.07889808704 -0.194888
+0.3180009793 -0.641190515 -0.00799
+0.3259719304 -0.6442976407 -0.01233
+-0.1342436266 -0.9351494949 0.00062
+-0.1331690086 -0.9450706778 0.00062
+0.3191457657 -0.0274203779 -0.249062
+0.329447979 -0.03167165241 -0.390394
+-0.8634963718 -0.006620555952 -0.15672
+0.3654495452 0.2718009403 -0.103202
+0.386039407 0.2859651774 -0.238908
+-0.1095606781 0.1449207463 -0.012118
+-0.1006061527 0.1384883396 -0.013848
+-0.1118038549 -0.6239027556 -0.003834
+-0.1207232557 -0.6255291902 -0.00918
+-0.1487716118 -0.05252409466 -0.009776
+0.02580496455 -0.03520374266 0.00062
+0.03216854427 -0.03598153667 0.00062
+0.2811693149 0.7005988382 0.000618
+-0.6114708866 -0.1834761481 -0.171232
+0.2469029035 -0.6221658725 0.00062
+0.03871639121 -0.02362480411 -0.003524
+0.04052281419 -0.02211228786 0.000616
+0.3418017371 -0.4931965745 -0.01649
+-0.2522923521 0.3222477573 -0.011116
+-0.3393666278 -0.3811630587 -0.070172
+0.180151251 0.0007614296998 0.00062
+0.0363447055 -0.07360792609 0.00062
+0.04188785473 -0.04965858313 -0.001536
+0.1886856345 0.6035970995 -0.002446
+0.1851462601 0.5893545519 0.00062
+0.2776481734 -0.6677384373 -0.003166
+0.2693125479 -0.664261371 -0.0019
+-0.2243397409 -0.8220609289 -0.135026
+-0.2075178458 -0.8137882603 -0.093726
+-0.2064967682 -0.7946958168 -0.085148
+-0.3179717657 -0.4589351137 -0.069178
+-0.3436686642 -0.4382596595 -0.090534
+0.3500507496 0.0505691061 -0.254102
+-0.1416072055 0.1397605586 -0.01461
+0.6880832467 -0.3305419182 -0.105436
+0.7388258537 -0.2643911144 -0.094614
+0.2876078604 0.6509176369 -0.010084
+-0.4596392501 0.3489567112 -0.187318
+0.08964437551 -0.06016368771 0.00062
+0.0869696709 -0.05539399171 0.00062
+0.08281602654 -0.05539162535 0.00062
+0.07702248361 -0.05395298174 0.000618
+0.09568610352 -0.09087305347 -0.002674
+0.183119078 -0.2298119709 -0.002322
+-0.1859427984 -0.7760111991 -0.037728
+0.9001028624 -0.05247551362 -0.063356
+0.9393988487 -0.02106481774 -0.068672
+0.9539904609 -0.04683776623 -0.073734
+-0.162224438 -0.06572315678 0.00062
+-0.07160747134 -0.1159991521 -0.006786
+-0.08872417437 -0.1262837 -0.004198
+-0.08313558451 -0.1165020085 -0.006052
+-0.2906343563 -0.616534856 -0.138806
+-0.2532417458 -0.6059360817 -0.099812
+0.01045370523 0.08693102179 -0.024662
+0.2533283059 -0.6017019693 -0.001344
+-0.3256858567 -0.2734268496 -0.049362
+0.3403081922 -0.1767516967 -0.490514
+-0.369792744 -0.1564594331 -0.06528
+-0.1775278152 -0.06012900684 -0.007266
+-0.1887853766 -0.0655036106 -0.008524
+0.2150062493 0.6547193286 -0.003414
+-0.7336250728 0.0517597462 -0.186268
+0.1290458579 0.1520215407 0.000602
+-0.2746855476 -0.2460001432 -0.028034
+0.03964589121 -0.04750960645 -0.002992
+0.180054071 -0.1719853753 -0.007566
+0.6499034447 -0.03712904077 -0.124612
+0.6025320406 -0.07459896846 -0.126402
+0.04219803736 -0.05577761869 -0.000858
+0.04138280404 -0.05768017347 -0.00338
+-0.1174651263 -0.6163846424 -0.005704
+0.175728514 0.005607720593 0.000614
+0.0882700137 -0.02945863981 0.000618
+0.09007791357 -0.03110348158 0.000604
+0.09279304187 -0.02701993382 0.000614
+-0.02264309283 -0.0289142528 0.000618
+0.3121137152 -0.6363216337 0.00062
+0.3146162352 -0.6370113429 -0.003068
+0.09602766487 -0.04086214167 -0.0025
+0.03690405101 -0.0348218259 0.00062
+0.03527264618 -0.0354941304 -0.001858
+0.03744452179 -0.03651354947 -0.003574
+0.02811244998 -0.06982395821 -0.001216
+0.03045474195 -0.06869445892 0.00061
+0.2032950345 -0.2899392825 -0.012812
+0.1962472685 -0.3066098024 0.00062
+0.09673641657 -0.03804492366 0.000612
+0.09621927691 -0.0389963771 -0.002868
+-0.2142427274 0.1288946178 -0.018632
+-0.2323489526 0.1128698314 -0.020816
+-0.2168456505 0.1144803783 -0.019094
+0.4457188109 -0.469724755 -0.104608
+-0.4176666834 0.479971885 -0.10061
+-0.118550805 -0.566421656 0.00062
+-0.1158572081 -0.5768311093 0.00062
+0.3098659065 0.7015227909 -0.009158
+0.3263108902 0.7016266535 -0.019276
+0.3244809391 0.7145371048 -0.022404
+-0.01021022455 0.03163874096 -0.034468
+0.09038331181 -0.03356696151 0.00061
+0.2945492146 0.0007354673783 -0.048598
+0.06234987033 0.1979168759 -0.013226
+0.07009534683 0.2056367721 -0.01006
+0.2443420638 0.5302067211 0.00062
+0.2440913578 0.5363806454 -0.003112
+0.2269355398 0.5282066587 -0.00138
+-0.2577619274 0.2252970468 -0.009944
+-0.2650696458 0.2176350028 -0.01894
+-0.2545618564 0.2164315035 -0.013704
+0.04065886181 -0.04950108237 -0.002304
+0.03881455081 -0.05017907475 -0.004192
+0.06603740138 -0.05755655268 0.000618
+0.06351283907 -0.05480361022 0.00062
+-0.4065720336 -0.5574139929 -0.1675
+-0.3497225922 -0.4717150941 -0.110066
+-0.3750904943 -0.4537564826 -0.11669
+0.193352349 -0.5292553913 -0.00231
+0.2001498449 -0.5231910199 -0.003178
+0.03573518294 -0.07783662899 -0.005086
+-0.1807073951 -0.1176596982 -0.001864
+-0.1891445135 -0.1120345873 -0.00159
+-0.1951214227 -0.1154699606 0.00062
+0.2214463373 -0.423529697 -0.004494
+0.085274089 0.0769762135 -0.025152
+-0.3315362744 0.3166584833 -0.0241
+-0.3046315029 0.3152195035 -0.023034
+-0.320333074 0.3349378674 -0.021414
+-0.1199473046 -0.7646728043 0.000618
+-0.1262719186 -0.7577500559 -0.002124
+-0.0219526237 -0.02397478391 0.00062
+-0.02214047162 -0.0263697852 -0.001484
+0.3186200853 0.07072056809 -0.035408
+0.3192999865 0.07680258739 -0.016414
+0.3132541122 0.07578207875 -0.009428
+0.3965648967 0.0527199478 -0.415818
+0.04430770011 0.8481947222 -0.003514
+0.03601089699 0.8451115052 -0.004466
+0.1705501595 0.002407714312 0.00062
+-0.3342412893 0.5141421651 -0.01437
+0.2873321504 0.7548575145 -0.007898
+-0.1912546248 -0.4445664787 -0.011926
+-0.1844646585 -0.4539298064 -0.008732
+-0.1811873537 -0.4433658912 0.000618
+-0.05181107439 -0.03805974168 -0.009464
+0.05574947609 -0.08808064066 0.00062
+0.05701452995 -0.08385474048 0.00062
+-0.5157038595 -0.3876028658 -0.153808
+-0.4608106802 -0.4015766785 -0.146702
+0.3189784262 0.5322889475 -0.06956
+0.3160037765 0.5151945397 -0.083156
+0.06374526659 -0.07231662935 0.00062
+0.05882053324 -0.06670668934 0.00062
+0.3662668927 0.1622002083 -0.23324
+0.3025143889 -0.001406763099 -0.11567
+0.02443712371 -0.06650157447 0.00062
+0.01506141964 -0.066848334 0.000618
+-0.1856750144 0.1344057124 -0.017594
+0.09029837995 -0.07504881696 -0.00138
+0.08950092643 -0.07305167505 -0.001272
+0.08825968461 -0.0733951308 0.00062
+0.7417505474 -0.2058638645 -0.065952
+0.09579443645 -0.04241573554 -0.00338
+-0.8362959933 -0.06538110144 -0.119736
+-0.288377791 0.5192956265 -0.006314
+-0.2791762681 0.5139432687 -0.005264
+-0.08114166436 -0.01493580898 -0.012024
+-0.06694647542 -0.03874375941 -0.010106
+-0.4328267645 0.07235763859 -0.0766
+-0.4754461621 0.09652537472 -0.173712
+-0.512295523 0.1039423342 -0.219144
+0.2613402937 -0.6732330218 -0.001276
+0.5633525514 0.2911990396 -0.584904
+0.1440730676 0.04194956012 -0.00446
+0.02642715252 -0.01262351133 -0.00921
+0.02496385103 -0.009039752945 0.000604
+-0.4224143078 0.5143776105 -0.064068
+0.01267178718 -0.07496406799 0.00062
+-0.8920854162 0.1599120376 -0.364614
+-0.723791447 0.318613266 -0.310056
+-0.7455648204 0.2778444446 -0.348848
+-0.08288261755 -0.1548026998 0.00062
+-0.1435817735 0.01353886164 -0.013276
+0.3112150473 0.06765974927 -0.028502
+-0.2006286022 -0.06916739474 -0.010454
+-0.1950770428 -0.07353052872 -0.005562
+0.2941781284 0.2495862666 0.00062
+0.2995262177 0.2466599322 -0.004624
+0.062134138 -0.07874278979 0.00062
+0.5111492865 0.4563861077 -0.48344
+-0.108530698 -0.01720610893 -0.012018
+-0.1250020672 -0.01013489375 -0.010694
+0.09071434811 -0.05281609146 -0.000906
+0.09192834294 -0.05243907402 0.00061
+0.0916163656 -0.05154215755 -0.004582
+-0.2490984659 0.1982245841 -0.01938
+0.2446287211 -0.6197861025 -0.000592
+0.2422120457 -0.6177352199 -0.000822
+0.2454132877 0.7741821832 0.000502
+0.2454944378 0.7697960465 0.00062
+0.2507413551 -0.4453569896 -0.013764
+0.5249458983 -0.02474040875 -0.479226
+0.5466034218 -0.05256362819 -0.277188
+0.5582348144 -0.02117357819 -0.39988
+0.3398438011 -0.03104351317 -0.433188
+-0.09171361933 0.1709925731 -0.005396
+0.09023816277 -0.01975364605 0.00062
+0.09414535641 -0.01525923368 0.00062
+0.3264509784 0.1553951646 -0.009004
+0.7332619752 -0.1486483929 -0.048116
+0.3246326144 0.07470836329 -0.092438
+0.3301932251 0.08032365712 -0.149004
+0.3228535027 0.08171710905 -0.031984
+0.03232323931 -0.0544705232 -0.003792
+0.03120871616 -0.05314416669 -0.004344
+0.03006465314 -0.05544026156 -0.00538
+-0.007821595942 0.8892137927 -0.06786
+-0.02297226401 0.8925381682 -0.047478
+-0.3316952322 -0.2971275323 -0.049136
+-0.3149543768 -0.2887938727 -0.048752
+0.184473084 0.0007799031917 -0.00138
+0.1867954763 -0.01310295153 -0.008708
+0.1828372658 -0.01066544354 -0.005142
+0.1818020703 -0.01546142158 -0.009302
+-0.219684374 -0.4519560106 -0.026348
+-0.2092758328 -0.4618417884 -0.026508
+-0.2064319255 -0.4453009272 -0.023378
+-0.1219869778 0.1922895912 -0.003876
+0.05879548322 -0.05936494517 0.000618
+0.04701558359 -0.08837405932 -0.00137
+0.04859250326 -0.09233048672 0.00062
+-0.2025184793 0.1652337263 -0.017118
+-0.2127385859 0.1784004862 -0.016678
+-0.183470656 0.1857932849 -0.009358
+-0.2178751807 0.07026924675 -0.019984
+-0.2566180799 0.05083652404 -0.02421
+0.06644001375 -0.01666065906 0.00062
+0.06541457533 -0.01936805696 0.00061
+0.04239650132 -0.06097650536 -0.003104
+0.06641672082 -0.02292933652 0.00062
+0.06500745526 -0.02124142839 -0.002818
+0.0630603216 -0.02205717029 -0.003016
+0.2123486845 -0.4269619248 0.00062
+0.2572439651 0.6369051632 -0.013144
+-0.1184728138 0.0005170873491 -0.011994
+-0.1280858821 -0.7943778551 0.00062
+0.006714054876 -0.05093721834 0.00062
+0.2783759371 -0.5894549307 0.000618
+-0.1779594486 0.1632629987 -0.012434
+-0.1854337435 0.1532417513 -0.016188
+0.01387595564 0.8551577915 -0.010536
+0.1725482382 0.005780112418 -0.002336
+0.1724301366 0.01014245718 -0.003012
+0.03795639337 -0.05098646045 0.00062
+0.4205780797 0.1580705385 -0.366398
+0.4107412064 0.1416935634 -0.363298
+-0.08533771454 0.1609548221 -0.010314
+0.3355612703 0.06086358536 -0.20913
+0.3412019904 0.05385499993 -0.200904
+-0.01585382077 -0.07376604227 -0.005684
+-0.02648508198 -0.07761550049 -0.007654
+0.2452599863 -0.6128673033 0.00062
+0.2449075629 -0.6156680779 0.000618
+-0.2871396698 -0.3858550288 -0.033586
+0.08475805173 -0.02157199752 -0.003112
+0.1453374598 -0.1177165176 -0.00338
+0.1365196068 -0.1196416888 0.00062
+0.1403953388 -0.1250581486 0.000498
+0.0147432893 0.8786570904 -0.017046
+0.02463378065 0.8820215491 -0.015636
+0.3163204043 -0.01497566573 -0.210804
+-0.3861025779 0.3839781285 -0.028084
+0.08336614759 -0.05134251793 0.00061
+0.3071003615 0.03714588463 -0.028676
+0.4660528976 -0.3856950269 -0.080886
+0.4911298135 -0.3499096585 -0.0495
+0.3659917462 0.02650070647 -0.471814
+-0.1446134742 -0.1326021182 0.00062
+0.05666483165 -0.06492010845 -0.00059
+0.178845483 -0.1412522505 -0.008778
+0.08568492386 -0.02557013493 0.000604
+0.05117914672 0.05513780487 -0.028114
+0.4103185683 -0.1174381012 -0.494586
+0.06652764986 -0.053698615 -0.000684
+0.5830294756 -0.2247448755 -0.07717
+0.6016810233 -0.214512645 -0.071918
+0.585605485 -0.1704167921 -0.082918
+-0.009040123291 -0.04765861948 0.000616
+-0.00703667665 -0.04742176208 0.00062
+-0.7006107222 0.02957558355 -0.171782
+0.07591412414 0.04726351896 -0.02996
+0.20458879 -0.5148851641 -0.003336
+-0.06533977911 -0.08753594227 -0.008584
+-0.07674331443 -0.09649575008 -0.00734
+-0.06509626892 -0.1078136681 -0.007694
+-0.02264412551 0.0359389823 -0.016986
+0.0097944888 0.1630086154 -0.017818
+-0.01049828643 0.05624468485 -0.02546
+-0.01054345258 0.06818814904 -0.023102
+0.3042700508 0.3691766478 -0.016264
+0.1440725787 0.02741577308 -0.007268
+-0.2109577713 -0.4169549606 -0.024518
+-0.21021605 -0.4303085653 -0.022608
+-0.9268946182 0.02921651539 -0.172128
+0.02412036561 -0.08463055638 2.2e-05
+0.02397453373 -0.08315558792 0.00062
+0.2880403945 0.3535571775 0.00062
+-0.09495324612 0.03761116857 -0.01502
+0.006594241094 0.2521986364 0.000618
+0.1891898664 0.5442707325 0.00062
+0.3065452888 -0.02378157101 -0.206252
+0.3103603406 -0.0363722157 -0.29631
+0.03106833001 -0.06759760444 0.00062
+0.2527594616 0.6697872533 -0.00575
+0.2460426075 0.6640657292 -0.00512
+-0.4796055002 -0.4287732578 -0.157328
+-0.001426981187 -0.02295338438 0.00062
+0.838612553 -0.1493020882 -0.075236
+0.81266337 -0.1363301616 -0.05857
+0.02652793064 0.8922086226 -0.01686
+0.03098620234 0.8747295727 -0.01165
+0.02183175619 -0.01815578286 -0.012988
+0.3192631329 0.6465151308 -0.013912
+0.3102190818 0.6517791867 -0.010722
+-0.01897091394 -0.1049365147 0.000616
+0.2812720947 -0.463430368 -0.020242
+0.2701327313 -0.4545885427 -0.019106
+0.2288851914 -0.523440297 -0.006532
+0.316807327 0.08149772291 -0.011362
+0.3477547278 0.02712637824 -0.305634
+0.3467805527 0.03550041865 -0.245872
+-0.09541359844 0.1631580746 -0.007816
+0.1233554286 0.08090514689 0.000566
+-0.3574789158 0.6258337206 -0.003234
+0.3668678525 -0.06226745801 -0.452418
+0.3092048107 0.6799780988 -0.00338
+0.3119132477 0.6880694344 -0.006772
+-0.08200100014 -3.537610786e-05 -0.012272
+0.1755201357 0.01403719324 -0.00379
+0.1912394327 -0.2820309836 -0.0046
+-0.5331468185 -0.01918321566 -0.135432
+0.2944733781 0.7275819639 -0.004848
+0.2872277838 0.7299240015 -0.005058
+0.3541296079 0.1175434192 -0.179274
+-0.1342150434 -0.861618196 -0.00694
+0.08868042859 -0.04959523335 0.000618
+0.3043736167 0.7058495977 -0.005676
+-0.1819591644 -0.7273848392 -0.026156
+0.44656301 -0.08471094216 -0.486256
+-0.4489899792 0.08854888078 -0.116948
+-0.4264720816 0.09898915307 -0.043462
+-0.1103288478 -0.700068172 -0.00387
+-0.114096996 -0.7073480543 -0.004456
+0.04746430344 0.04402162641 -0.028538
+0.05604882164 0.03660174274 -0.027596
+0.1643409066 -0.02978908257 -0.010772
+0.1623252151 -0.0215707901 0.000616
+0.1696972894 -0.02366292992 -0.009274
+0.252326727 -0.4758393578 -0.010438
+-0.274245445 0.3314243844 -0.017906
+-0.2695574495 0.3088383785 -0.01862
+-0.2649786839 0.3225358523 -0.017322
+-0.3478176726 0.4551173105 -0.018316
+-0.2381685109 -0.1260510348 -0.014472
+0.04498321996 -0.08491712062 0.00062
+0.2845534547 -0.006252982783 -0.005284
+-0.08337697804 -0.09079826028 -0.007792
+0.009581059673 0.9168475801 -0.049538
+0.3091543139 0.2256216257 -0.005918
+0.3010916602 0.2292529903 0.00062
+0.3088332895 0.2355007119 -0.009964
+0.2358901628 -0.5539768797 -0.004276
+-0.1307744026 -0.6246820243 -0.018712
+0.3285039312 -0.6040533414 -0.01009
+0.3228080564 -0.5996307449 -0.005892
+0.09661755499 -0.04916223803 4.2e-05
+0.09707351871 -0.04944715164 0.00062
+0.2424775322 -0.6210011698 0.00062
+-0.1311561472 0.1931041054 -0.003616
+-0.1315984058 -0.9239944129 0.000522
+0.08215960462 -0.04806698079 -0.00784
+0.5497989111 -0.2928829074 -0.017848
+0.3006783864 0.6786164114 0.000614
+0.4278209278 0.278493186 -0.37779
+0.4346304234 0.3039397263 -0.397602
+-0.2001444725 -0.003244608672 -0.01445
+-0.2046229787 -0.01527662219 -0.013498
+0.08840838749 -0.030673403 0.00062
+-0.5957439633 -0.2446392371 -0.160974
+0.2960446829 -0.6287565131 0.00062
+-0.1403831572 0.04708195012 -0.015504
+-0.2568499364 0.3320119692 -0.015116
+0.191598221 -0.009724492483 -0.005958
+0.0813971438 0.1327248608 -0.020934
+0.0970264574 0.158540272 -0.01555
+0.1029853018 -0.02483606741 0.00062
+0.09349809203 0.1770354339 -0.014468
+-0.6188763059 -0.04991868413 -0.169404
+0.341592356 -0.5227170704 -0.01626
+0.3046976395 0.5658146024 -0.034576
+-0.5168534892 0.1413370007 -0.206686
+-0.4914226393 0.1222185675 -0.15163
+-0.2615397981 0.2452964189 -0.00609
+-0.05915176707 -0.1574559663 -0.001562
+-0.04342768828 -0.162155214 -0.000844
+0.09767504772 -0.02763700848 0.00062
+-0.01372701578 0.07993764458 -0.02322
+-0.01913385024 0.09145003347 -0.021134
+0.05844259835 -0.08477263373 -0.001874
+0.06202306179 -0.08330242447 0.00062
+0.1657232687 -0.101304697 -0.015506
+-0.1369228751 -0.09156899965 -0.006354
+-0.147748561 -0.08804110088 -0.005596
+0.09528477634 -0.02214172656 -0.003582
+0.09535105008 -0.02668175192 0.000572
+0.2185645518 -0.08937721328 -0.023548
+-0.429303695 -0.05723447348 -0.053134
+0.1616394259 -0.1271120374 -0.002666
+0.279775406 -0.3382622063 -0.337156
+0.2697531421 -0.35939964 -0.218418
+-0.1546447753 -0.07013509628 -0.001138
+0.06220222558 0.9074679768 -0.005948
+-0.4701109335 0.02041113827 -0.052608
+-0.1580286146 -0.1240211162 -0.001972
+0.2796833543 0.3762180496 0.00044
+0.2785356107 0.3848164859 0.00062
+-0.1675737945 -0.3003188004 0.000618
+0.05769264249 -0.06614529076 -0.000116
+0.2920850776 0.253030373 0.00062
+0.295785765 0.2559742124 -0.004336
+0.1404473743 0.05191083411 -0.008536
+-0.2569116836 -0.07002732683 -0.023632
+-0.1650237059 -0.5583397585 -0.020952
+-0.4770000557 0.4229608293 -0.2383
+-0.3750418716 -0.3528360468 -0.08693
+0.03016516289 -0.06156566974 -0.004236
+0.3441081155 0.04413058803 -0.224774
+0.009644254033 0.231256715 -0.00538
+0.007297074455 0.2206738517 -0.007284
+-0.2145947182 -0.7603670634 -0.067856
+0.4857618416 -0.2092158508 -0.113188
+0.466632633 -0.1876903532 -0.171508
+-0.6527848148 0.3613332769 -0.338696
+-0.2697535432 0.5006236879 -0.005864
+-0.2853526262 0.5079429657 -0.008352
+0.06655042456 -0.03016810383 0.000608
+0.3928484556 0.06616178199 -0.42466
+0.3781028848 0.06833090446 -0.383164
+0.08105015729 -0.05301747531 -0.006328
+0.2843361004 0.7399598991 -0.007268
+0.02636956418 -0.08781837482 0.00062
+0.007317805763 -0.05739877578 0.000602
+0.005187118639 -0.05774219669 0.000616
+0.2360190838 0.5561983861 -0.006874
+0.02493942684 0.1834216033 -0.015312
+-0.01225343546 0.8294275678 0.000452
+0.005785593978 -0.05427507995 -0.001206
+0.0258908572 -0.0530876563 0.00062
+0.02737859017 -0.05015422274 -0.007972
+0.3565816215 0.5359586055 -0.213434
+0.3533220797 0.5656712984 -0.205448
+-0.005717437644 0.8313621893 -0.006704
+-0.1985781916 -0.4110555075 -0.018754
+0.5359828504 0.003261258767 -0.513362
+0.3583500905 -0.5705889283 -0.014994
+0.3453344678 -0.567226671 -0.014692
+0.02236944319 0.8231786851 0.000532
+0.4811738725 0.4917239118 -0.468136
+-0.1479440114 0.7705468861 0.00042
+-0.1459185089 0.7674496632 0.00062
+0.3987034294 0.08980078567 -0.40514
+0.3803768593 -0.5397900097 -0.017284
+-0.02217938852 -0.04854711976 -0.007838
+0.4271872417 -0.2482770134 -0.145046
+0.1916984499 0.59442381 -0.004068
+0.2119097261 -0.5678780378 -0.002574
+-0.07206693433 0.175979545 -0.009228
+-0.06654117229 0.1845637733 -0.009524
+0.3175492612 0.241606096 -0.018514
+0.3136579407 0.2500322324 -0.01869
+-0.08958390694 -0.007330473703 -0.012576
+0.2023929377 -0.3976241583 0.00055
+0.02907139848 -0.08190961989 0.00062
+0.02716872925 -0.08017268457 0.00062
+0.1516634832 0.0419831986 2e-05
+-0.2595580073 -0.5267376112 -0.03938
+0.03603673343 0.2488747957 0.000442
+0.03796469667 -0.1052067796 2e-05
+-0.2046181699 -0.6551196806 -0.079996
+-0.1966918859 -0.6728443341 -0.106034
+0.1535790693 0.0433575992 0.00042
+0.2575286811 -0.3413215845 -0.31047
+0.1309977273 0.05889032206 -0.004152
+0.707821188 0.02791097396 -0.210008
+0.08641433187 0.04278249231 -0.032554
+0.01423315698 -0.02403865889 0.00062
+0.01646203481 -0.02616940547 0.00062
+0.009001279095 -0.02881068283 0.00062
+0.2685119385 0.7065592938 0.00062
+-0.1822931718 -0.07330727323 0.00062
+-0.2264979232 -0.1058868227 -0.011642
+0.0005548508492 0.07683931111 -0.025072
+0.2243529505 0.6039012494 -0.010892
+-0.07318924499 -0.0894957112 -0.00819
+-0.02847495674 0.1031795484 -0.02218
+0.4223136592 0.1083084846 -0.409194
+0.4401478161 0.1029781154 -0.531104
+0.4345612333 0.1210296953 -0.391958
+-0.2432764397 0.2108231327 -0.007888
+-0.3211613304 0.4737483104 -0.015498
+-0.113280083 -0.6553350245 -0.006316
+0.04457142343 -0.0940608649 -0.001098
+0.04386716321 -0.09166303568 0.00062
+-0.3391446195 -0.5309652686 -0.123536
+-0.2222524864 -0.4395914855 -0.022526
+0.3700262269 0.2485900826 -0.130304
+0.3989180391 -0.4924867832 -0.029916
+0.2911679686 0.5544284297 -0.029996
+0.03450196734 -0.07350387213 -0.000126
+0.2168854971 0.01405244313 0.00062
+0.1831657635 0.01951746685 0.00062
+0.2818711476 0.3687780133 0.00062
+0.05914726352 -0.02078216218 0.000618
+0.05852874356 -0.02187778417 -9.2e-05
+0.2918826753 0.302506143 0.00062
+0.142447016 0.03229332593 0.000608
+-0.07073014584 0.07160442363 -0.023366
+-0.06986728646 0.08511619936 -0.020184
+0.4419628773 0.2568659744 -0.321676
+0.2017244438 0.5416867142 0.00062
+0.106713706 -0.03456295902 -0.017528
+0.1027614911 -0.03400913473 -0.008362
+0.3547406438 -0.4801735356 -0.018566
+0.5145130334 -0.3636251052 -0.058936
+0.3207167091 0.1520889963 -0.00317
+0.3211044717 0.1593966557 -0.00263
+0.2262758693 0.0002096953741 -0.03272
+0.2194064298 0.005694532227 -0.009228
+0.2736990976 -0.6045546824 0.000356
+-0.06476716574 0.0299816365 -0.015428
+0.0284667581 -0.04726718224 -0.00651
+0.3626691053 -0.619265176 -0.014432
+-0.8582286222 0.04224501247 -0.179376
+0.5097214501 -0.3388641649 -0.026324
+0.4922559727 -0.3277561934 -0.02699
+-0.3040997028 0.5036545481 -0.011696
+-0.3023567189 0.5161108927 -0.009984
+0.7121062434 -0.06477761416 -0.067152
+0.01223787274 -0.07184326509 0.00062
+0.01359739131 -0.07293396214 -0.002208
+-0.3269208486 0.5551302611 -0.00972
+-0.3207024958 0.576596919 -0.00568
+0.732622105 0.1095451927 -0.45669
+0.7695109749 0.1172794458 -0.346062
+0.057049798 -0.06825029267 0.000262
+0.2793655455 -0.5077828635 -0.012396
+0.2870931012 -0.5145930865 -0.012786
+-0.1351888286 -0.8863464282 0.000618
+-0.135661711 -0.8946524008 0.00062
+0.3056943888 0.7126491245 -0.009244
+0.3809466969 -0.05071959381 -0.49094
+-0.7667149624 -0.1764527721 -0.123384
+-0.735877132 -0.2054237489 -0.123272
+0.1485423542 0.04418987619 -0.003268
+0.3576060846 -0.5826262109 -0.01485
+0.02759391305 -0.07807180276 0.00062
+-0.3862275074 0.44855561 -0.031258
+-0.1466753389 -0.7373531108 -0.011048
+0.02736641771 -0.03366123536 0.00062
+0.09372903164 -0.02184726703 0.00062
+0.2781159951 0.4579012259 -0.010118
+0.3036974005 0.6990659845 -0.00338
+-0.2127244467 -0.07358877595 -0.012222
+-0.7540012572 0.160188431 -0.333212
+-0.7665616462 0.09134926664 -0.23199
+-0.7934479624 0.1389586562 -0.302604
+0.2924439822 0.2740307109 0.00062
+0.2472784146 -0.5436017239 -0.004392
+0.4815741344 -0.4295861671 -0.105588
+0.03058031699 -0.06362535778 -0.003354
+0.03169474283 -0.06312340365 -0.001904
+0.03148104034 -0.06469620723 -0.005206
+0.3023049144 -0.4399636616 -0.216212
+0.2948242639 -0.45452898 -0.052574
+0.04526558968 -0.09150186371 -0.00086
+-0.1592978692 0.1055852081 -0.01697
+0.04041617433 -0.03796393679 -0.002788
+-0.146080766 0.7769758638 0.00062
+-0.1737129086 0.1033094784 -0.015514
+0.1929758656 -0.01561005336 -0.011154
+0.2173838379 0.6705579525 -0.000324
+0.2222169929 0.6646105805 -0.003522
+-0.2697914704 0.2414093183 -0.016286
+-0.2674598295 0.255261843 -0.013826
+-0.2794903006 0.2577165939 -0.022484
+-0.4600875289 0.1456358699 -0.025188
+-0.449477708 0.1302374272 -0.035876
+0.009620097323 -0.07056442275 0.00062
+0.3119542438 0.6619607808 -0.009322
+-0.6785458142 0.3250687763 -0.345646
+-0.4884786399 0.3433478836 -0.248136
+-0.2625661352 -0.1413874439 -0.018156
+0.29499722 -0.6176715296 -0.000554
+0.1666674163 -0.1191030619 -0.008804
+0.0692735248 0.9320234615 0.00062
+0.06918910876 0.9119680572 -0.002696
+0.1861969282 -0.1370929443 -0.02144
+0.2933408931 -0.007548975464 -0.089048
+-0.1708717149 0.1726850942 -0.010504
+0.6919124033 -0.05399123735 -0.074696
+-0.1836230263 0.1105144142 -0.01517
+-0.2094509895 0.09150459855 -0.019218
+0.2580652364 0.5466639106 -0.014132
+0.2533356209 0.5351453284 -0.008482
+0.2588326555 0.5278281376 -0.012426
+-0.06852646675 -0.1570924917 -0.0017
+-0.06955328798 -0.1453085449 -0.003026
+-0.1741866199 0.7742277387 0.00022
+-0.1793774471 0.7719471972 2e-05
+-0.1630799494 -0.4866229568 -0.005494
+-0.157687235 -0.4909225696 -0.00349
+-0.3574822713 0.3888007448 -0.023542
+-0.1818469683 0.1442097751 -0.017234
+0.1976902819 -0.3586796305 -0.005688
+0.08073590812 0.1907552267 -0.013092
+-0.1904913083 -0.07937113338 0.00062
+-0.1955280935 -0.08001845777 0.00062
+0.009223586483 -0.02383724856 0.00062
+-0.1281279996 0.03525704384 -0.01345
+0.2460914166 -0.6017274509 0.00062
+0.2447383042 -0.5996674318 0.00062
+0.2437569666 -0.6113770798 0.00062
+-0.1394199715 0.1995083008 -0.003816
+-0.1980597046 -0.7611619314 -0.04361
+-0.1923700917 -0.7472823151 -0.032332
+-0.3281740283 -0.2275856391 -0.051492
+-0.3101108011 -0.234468127 -0.038514
+0.3824124067 -0.4216813655 -0.118766
+-0.05108156691 0.8637119798 -0.039176
+-0.04019612873 0.8670031484 -0.028062
+0.3380758892 -0.2268263356 -0.382856
+0.3158170213 -0.2091691234 -0.489542
+-0.2051052098 0.121299949 -0.016514
+0.03999416125 -0.04295562267 0.000614
+0.03922305092 -0.04229787815 0.00062
+0.03817867135 -0.0428840388 0.000604
+-0.311065774 0.5346031794 -0.010316
+-0.3063514743 0.5264332598 -0.010094
+0.4311305893 0.03527392422 -0.540506
+0.9684223696 -0.06863454732 -0.083744
+0.2991912424 0.7202856415 0.00062
+0.3077100591 0.7299276743 -0.014996
+0.0907095936 -0.0810187268 0.00062
+-0.3278390554 -0.3633187235 -0.045612
+-0.1359555273 -0.7674601593 -0.0054
+-0.1264483935 -0.7703633438 -0.002348
+0.2468809138 -0.1854299075 -0.210778
+0.2699907951 -0.1749770134 -0.356724
+-0.3666119449 -0.5656295723 -0.149658
+0.3650171021 0.07427037001 -0.325694
+0.3748896326 0.0798160173 -0.268126
+0.2964548203 -0.619611508 0.000616
+-0.01759072396 0.01254965258 0.00062
+-0.01697258254 0.008660300677 0.000618
+-0.2045237538 -0.6818184423 -0.116044
+-0.2153698111 -0.6833563226 -0.11293
+-0.2053307081 -0.696516849 -0.105048
+0.1616947972 -0.07871520265 -0.01801
+0.1587206471 -0.09262561167 -0.013732
+-0.7100854071 -0.1204940455 -0.13527
+-0.08177488084 0.1705501324 -0.00538
+-0.4159401464 0.3621232581 -0.03405
+0.02872262988 -0.06376585543 0.00062
+0.2492082735 -0.60558097 -0.00138
+-0.1709866238 0.1135867955 -0.0186
+0.3304879368 -0.3269951276 -0.26167
+0.3738548673 -0.3296045328 -0.15759
+-0.4066942614 -0.0686623269 -0.051788
+0.232708841 -0.7232854206 -0.003822
+-0.1245639826 -0.1103769911 0.00062
+-0.136152952 -0.1124260719 0.000618
+-0.1331970625 -0.1078363956 0.00062
+-0.1463043717 0.1586433154 -0.010072
+0.02402382518 -0.04171701557 0.00061
+-0.1514845863 -0.8187079769 -0.016
+-0.1418307335 -0.8128552394 -0.009834
+0.04197901949 -0.1019087827 -0.000776
+-0.4686489648 0.1245726374 -0.109854
+0.02840777196 -0.05059488382 -0.00938
+-0.1092079286 -0.6468806628 -0.003142
+0.2202659442 -0.4776648303 -0.006784
+0.3013611581 0.2235034627 0.00062
+0.01622310793 -0.02378903097 -0.003202
+0.01923093987 -0.02265649686 0.000616
+0.2973484361 0.2377440222 0.00062
+0.4616006605 -0.4122960366 -0.101914
+-0.209502989 -0.4055490645 -0.022236
+0.01080472328 -0.0777018001 0.00062
+0.05050793033 -0.1005897631 0.00062
+0.3404388235 -0.6024097243 -0.01466
+0.3012857073 0.2401118034 -0.003602
+0.1143284261 0.1059729951 -0.014512
+-0.8205645558 0.08533272141 -0.230088
+-0.8440381203 0.1339710531 -0.31984
+-0.9068219274 0.06043194204 -0.205478
+-0.1335944899 -0.9130580248 0.000522
+-0.135750915 -0.9016983385 0.000618
+-0.1398442346 -0.9122751174 -0.003822
+-0.2924937811 0.3183280744 -0.02031
+0.01340097055 0.8314956972 -0.00464
+0.1272069058 -0.1131829644 0.00062
+0.2393626133 0.5223656477 0.00062
+0.1260420427 0.06358508641 -0.017542
+0.3743984986 0.1702809176 -0.239602
+-0.1370817555 0.7821091868 0.000306
+0.08785505516 -0.05514631446 -0.001142
+-0.007643720351 0.01883726645 -0.015518
+-0.0977477696 -0.6852209435 0.00062
+0.09832489124 -0.0512089936 0.00062
+-0.007457669512 -0.007915461399 0.00062
+0.1984580345 -0.01095543799 0.000618
+0.2476869501 0.542935686 -0.008418
+0.08289522022 -0.03480843962 0.000596
+-0.2026603086 -0.7771679337 -0.056294
+0.2608974465 -0.1302117412 -0.16368
+-0.3126088687 0.4449030944 -0.015412
+0.01306671418 -0.02029095563 0.00062
+0.2537499664 -0.6039200713 0.000618
+-0.1111907989 -0.6659575505 -0.006578
+0.1972138433 0.5675243212 -0.004226
+0.2448870018 0.6938389206 3e-05
+-0.1377727621 -0.5400065399 -0.002358
+0.1921789905 -0.07732991516 -0.031762
+0.1492334249 -0.07416819638 -0.0203
+-0.3053853187 0.5555700018 -0.006548
+-0.1172227829 -0.1111601809 -0.001932
+-0.1282954407 -0.5681364959 -0.00369
+0.2889240936 0.3749323377 -0.006346
+0.290546902 0.3635412282 -0.005094
+0.2951493023 -0.188297065 -0.38938
+-0.4704358223 0.3214522603 -0.219358
+-0.006912533405 -0.09005853062 0.00062
+0.8427626989 -0.01893124958 -0.060926
+0.2384584184 -0.4871549266 -0.008684
+0.2844225897 0.4219462613 0.000618
+0.3285873742 0.3536271275 -0.034834
+0.05827765889 -0.07023545862 0.00062
+0.2370087002 0.5448826919 -0.005028
+0.01401574698 -0.06482494928 0.00062
+0.1531644578 0.04200999742 0.00042
+0.299894238 0.7307482414 -0.006966
+0.08997432156 -0.02127397364 0.000618
+0.09209314103 -0.02355610669 0.000604
+-0.1336940851 -0.6135886035 -0.018396
+-0.1430714655 -0.6893205056 -0.015954
+0.02096276388 0.830108008 -0.00284
+0.02292946387 0.8270247548 -0.001024
+0.02466860518 0.829650439 -0.001738
+0.3030432531 0.6004995256 -0.02706
+0.09003516367 -0.05017133061 0.00062
+0.02611549247 -0.08230936379 -0.000758
+0.02590477097 -0.08414285903 0.000618
+-0.421694475 -0.3982140767 -0.112452
+0.2308200465 -0.5157197033 -0.006962
+-0.4123900173 0.5018726321 -0.04917
+0.03718244386 0.2380465942 -0.004056
+-0.1094548969 -0.6781297654 -0.004982
+0.3032303791 0.06398275102 0.00062
+0.05195660428 -0.07835688215 0.00062
+-0.7815623367 0.1911364392 -0.34724
+0.02734884388 -0.0542993535 0.00062
+0.09742647894 0.185096362 -0.010948
+0.0974871737 0.1936062176 -0.007278
+0.3199711032 -0.6496338155 -0.011552
+0.2946662764 0.6759605784 -0.005906
+0.2465371552 -0.5891367802 -0.002678
+0.2509123504 -0.5838110564 -0.003102
+0.4136023147 -0.5476931467 -0.022432
+0.3176658396 0.2227716688 -0.015518
+0.02841926106 0.231784985 -0.00538
+0.02937906287 0.2225480071 -0.007746
+0.1544734087 0.03460180954 0.00052
+0.1551218291 0.03513542666 0.00052
+0.02245844108 -0.03462028386 0.00062
+0.2482783849 0.5307457129 0.00062
+0.2338754691 -0.006170490461 -0.014242
+0.2355510634 0.004443589147 -0.008072
+0.0851959182 0.05376955052 -0.02947
+-0.3414604857 0.3884698861 -0.02061
+-0.3392701909 0.4103068024 -0.018988
+0.5931903926 -0.01718609757 -0.35158
+0.03476974589 -0.06912780086 0.00062
+0.03548649642 -0.07232713725 0.000618
+0.2191045684 0.6466274957 -0.005454
+-0.1776392989 0.1238395689 -0.019186
+-0.2660522753 0.03582751882 -0.023246
+-0.1692196763 -0.4797448676 -0.007222
+0.2672292297 -0.1516610738 -0.33174
+0.03201089587 -0.06689169883 -0.003354
+0.3205089823 0.6913205923 -0.013794
+0.05854058725 -0.05670938273 0.000618
+0.34685675 0.3778642666 -0.26612
+0.2269697128 0.009390232636 -0.00497
+0.2481997215 0.5185914932 0.00062
+0.2478889667 0.5251143802 0.00062
+-0.02506928519 0.04964112673 -0.020564
+0.409191785 0.296298572 -0.282382
+-0.1644641733 0.7776293581 0.00057
+0.7297606914 0.04346249512 -0.217752
+0.7313719799 0.01348810482 -0.119468
+0.2888241383 -0.002260617156 -0.01249
+0.3142628142 0.1558575551 0.000484
+0.02468448812 0.8230718845 0.00062
+-0.1504969322 -0.5475777406 -0.009036
+0.3275546849 0.04713482592 -0.15479
+0.2064650287 -0.4810924518 0.000618
+0.15373403 -0.04321117755 -0.048948
+0.2522871102 -0.3006640699 -0.33208
+-0.03332205253 0.1166895276 -0.019574
+-0.2742935057 0.2663149734 -0.018836
+0.08772386098 -0.03037653307 0.00062
+0.2630602476 -0.597652164 0.00062
+0.2648276348 -0.5952502284 0.000618
+-0.2099081727 0.1566908813 -0.019216
+0.9079128628 -0.06968666939 -0.07231
+0.1011981354 -0.03999385669 -0.00938
+-0.09829170732 0.2157777627 -0.002696
+0.05783582383 -0.06474957503 0.00061
+0.01172971305 -0.06602547641 -0.00445
+-0.2173826901 0.4255445136 0.00062
+-0.2288901637 0.4285259543 -0.003386
+-0.2279681694 0.4192290672 -0.00382
+-0.2182629541 -0.02342256038 -0.0174
+-0.2138503182 -0.03324871304 -0.015074
+-0.09192387574 0.2003630758 -0.00338
+0.3697900203 0.5883597459 -0.23642
+0.05609306719 -0.02342125261 0.00062
+-0.1252772703 -0.617283359 -0.010414
+-0.3774848031 0.05700955017 -0.038268
+-0.1751635827 -0.8926301935 -0.067732
+-0.1605283419 -0.9059703192 -0.025804
+-0.4708590418 -0.4570131857 -0.154066
+0.6203011751 -0.2551620551 -0.069626
+0.2401336453 -0.6202681965 -0.000148
+-0.1632432106 0.217269218 0.00062
+0.1950913337 -0.1620358455 -0.028266
+0.04454202882 0.2035335056 -0.01348
+0.03620721802 0.2069780124 -0.012104
+-0.09471820989 0.2272968547 0.00062
+0.2013449783 -0.01683512723 -0.012368
+0.4540660618 0.1183920676 -0.545824
+0.4452022767 0.08401787602 -0.555084
+0.05810772089 -0.06324600056 0.000618
+0.3971429221 -0.3418605548 -0.112134
+0.4192269794 -0.3289781083 -0.099094
+0.155956556 -0.02752853398 -0.014116
+0.1576132897 -0.03451856349 -0.029482
+0.3084671891 0.5466797123 -0.04634
+-0.09910330569 0.7913257853 0.00024
+0.5449217869 0.03534921582 -0.506002
+-0.2251835945 0.4371554547 0.0006
+-0.2353826969 0.4360906312 -0.00486
+0.3095668862 0.2668632798 -0.01823
+0.3146689954 0.2745650567 -0.024486
+0.09707737823 0.07142778899 -0.02858
+0.1047539247 0.06345084341 -0.03055
+0.009873365032 -0.06773584086 0.00062
+-0.08543446326 -0.04855556923 -0.009312
+0.3757826415 -0.3566555265 -0.13073
+0.3497564797 -0.3467924899 -0.178638
+0.274081817 0.7425153623 -0.00787
+0.7841016527 0.01460265534 -0.064502
+0.8253270344 -0.004406408343 -0.069836
+0.2253046885 -0.4020814123 -0.013248
+0.2359463087 -0.3938957059 -0.01938
+0.4492580384 -0.2615867971 -0.086568
+0.3217808732 -0.4388405021 -0.12646
+-0.04742089118 0.1203155313 -0.01816
+0.0924665025 -0.07476986224 -0.00138
+0.09337907136 -0.07507797341 0.000608
+0.9819974109 -0.09409124377 -0.118852
+0.9515552876 -0.09010764337 -0.097974
+-0.1944490063 0.2041817563 -0.002718
+-0.01392024593 -0.02853355294 0.00062
+0.1403010482 0.00192323122 -0.019488
+0.1455236763 -0.006237737808 0.00061
+0.1495152059 0.002621009445 0.00061
+0.0277961235 0.829360385 -0.000664
+-0.1621828683 -0.05041395104 -0.010576
+0.08776361409 0.03112166302 -0.0355
+-0.2632149108 0.2676680827 -0.01168
+0.2078590777 -0.07537316809 -0.029026
+0.1988228438 -0.06364943122 -0.097856
+0.4295318333 0.1780242546 -0.328098
+0.2718438331 0.6634442137 -0.00789
+0.2784277828 0.6730005197 -0.006802
+0.2757143714 0.7076945829 -0.00138
+0.2784768591 0.706371435 0.000618
+-0.1032711342 -0.7272843096 0.00062
+-0.2407313375 0.3565635525 -0.009646
+-0.03437649226 0.2180615507 -0.005972
+0.3596756734 0.4168752281 -0.110846
+0.3880872176 -0.5956301833 -0.018974
+0.09317549689 -0.02433122898 -0.004872
+0.2814027446 0.7494874128 -0.008554
+0.4018262747 0.1287457654 -0.348522
+-0.3834270104 -0.05339844895 -0.051834
+0.1544840833 0.03564616168 -0.000606
+0.06256125532 -0.004132641605 -0.00669
+0.1461147533 0.03894088191 -0.00338
+0.03374374905 -0.03471822055 0.00062
+-0.1599983324 -0.4776261957 0.000412
+0.02859180455 -0.07665039197 0.00062
+0.09003216439 -0.02449213282 -0.00538
+0.3315918359 0.06579549389 -0.178708
+0.2228245449 -0.009023646284 -0.07638
+0.06046470837 -0.02445700937 0.00062
+0.03387831388 -0.0777158141 -0.00242
+-0.3986350139 0.5090219524 -0.022602
+-0.02183891964 0.001582296928 -0.001354
+0.02006873633 -0.01919950747 0.00062
+0.02920928246 0.9189278453 -0.02884
+-0.2397558029 0.3315792708 -0.003462
+0.3093227006 0.359189585 -0.01668
+-0.1963407571 -0.4553521777 -0.017428
+0.6394020957 0.3274279056 -0.596888
+0.2980562757 0.3754231385 -0.01274
+0.03415342591 -0.05272985134 0.000618
+-0.003788035603 0.08946682215 -0.022702
+0.3000960565 -0.629020687 -0.00094
+0.06865610788 -0.07947482274 0.000608
+0.03284902186 -0.07701450436 -0.003736
+0.07772732369 -0.02940086526 0.000618
+-0.5178851223 0.004711846271 -0.106316
+0.2613156896 0.666908395 -0.006996
+-0.02089413261 -0.02627778499 0.000616
+-0.2228695042 0.1773400361 -0.019206
+-0.2333049647 0.1553531974 -0.02137
+-0.2410905397 -0.6759835271 -0.14278
+-0.01513358857 -0.06262790849 -0.006294
+-0.1244955919 0.2247307725 -0.001912
+0.1248182029 -0.004633058116 -0.057166
+-0.2952191235 0.2299820287 -0.024476
+-0.2940275837 0.1997440596 -0.02428
+0.242107219 0.6136535403 -0.012666
+0.250293254 0.6188525229 -0.012738
+0.241792935 0.6224900349 -0.012208
+-0.3063605564 -0.5503603351 -0.107092
+-0.1656504023 0.7638622996 0.00062
+0.2488239457 -0.5737070829 -0.003756
+-0.1020955912 0.1695551895 -0.004506
+-0.2185026439 0.4127147365 -0.002692
+0.206246893 -0.03751289994 -0.023388
+0.2230039575 0.6148955731 -0.010112
+0.3171595917 -0.5977413235 0.00062
+-0.1066629321 -0.7070296732 -0.002052
+-0.3936442677 -0.1518480708 -0.081876
+0.2200387444 -0.4844097645 -0.007762
+-0.2846595487 -0.4937820821 -0.047142
+0.2582426834 -0.5799322242 -0.003524
+-0.2796429968 -0.2887233883 -0.026672
+0.06578319045 0.8913517497 -0.003
+0.309679842 -0.5788509938 -0.0047
+0.01175245993 -0.03914900351 0.00062
+0.3149687766 0.1633070797 0.00062
+0.2903793552 0.2828857939 0.00062
+0.2945423034 0.2847150708 -0.004178
+-0.08526686498 0.8221264627 -0.016306
+-0.003304046762 -0.07740686416 0.000618
+0.2589605064 -0.246102856 -0.288868
+0.2829468149 -0.2458357462 -0.433942
+0.3153511806 0.02456254654 -0.09602
+0.05617084417 -0.0001496688081 -0.012292
+0.3054805908 0.2196854267 0.00062
+-0.1259349298 -0.8729654212 0.00062
+0.3780338583 0.6156333845 -0.209064
+0.9045526262 -0.02649314637 -0.067316
+0.2688700899 -0.5124765319 -0.007826
+0.07135608156 -0.06495171666 0.000568
+0.03588956219 0.9011324548 -0.015286
+0.4145580287 0.3228235886 -0.35348
+0.1798869732 -0.0123480509 -0.005162
+-0.1993257643 -0.8552055946 -0.064972
+-0.2302310174 -0.01420743984 -0.020464
+0.2652124574 -0.3188742022 -0.367704
+0.3374920604 0.1477547183 -0.023854
+0.3332569224 0.141240974 -0.02125
+0.8648350085 -0.1650827648 -0.110642
+0.3005000762 0.3333959436 0.00062
+0.2864199375 0.6815842873 -0.006224
+0.2364184221 -0.7141113677 -0.003572
+0.244542062 -0.7104684148 -0.004442
+0.2529385878 -0.164498181 -0.221042
+0.2903373406 0.2911043274 0.000116
+0.189433178 -0.1728616963 -0.021876
+-0.03428370452 -0.1377299511 -0.003042
+0.3035958648 0.2198876641 0.00062
+0.1274915408 0.01162155848 -0.047438
+-0.04800805441 0.06724681278 -0.02379
+-0.1650067277 -0.3531047136 -0.004526
+0.2339555448 -0.1639107972 -0.124576
+-0.5227109427 0.2797573218 -0.205912
+0.2165345092 -0.4918297848 -0.006168
+0.5990508392 -0.2382337443 -0.063318
+-0.02224629158 -0.09821958554 -0.004576
+0.3204879826 -0.5805684606 -0.009746
+0.5110014609 -0.05190951186 -0.376156
+-0.171830387 -0.3329773326 -0.003512
+-0.1632418759 -0.3293283509 0.00062
+0.01247711878 -0.06925912627 -0.00266
+0.01395218256 -0.07126927428 0.000618
+0.35743727 0.2395490724 -0.083036
+-0.5739569357 -0.3556847634 -0.169302
+-0.1492388229 -0.8345789512 -0.014514
+-0.1401033597 -0.8250578052 -0.00783
+0.2568584244 0.5214402164 -0.009056
+0.2522813623 0.5264606195 -0.00408
+0.03674844958 -0.07721605872 -0.003318
+0.04015466148 -0.05569513471 -0.003518
+0.4594390577 -0.3002544454 -0.04343
+-0.03460678197 0.8165611927 -0.00338
+-0.03114700563 0.8261130129 -0.00338
+-0.9286407923 0.1098123433 -0.300122
+-0.1761340323 -0.4477905401 0.00062
+-0.04590346557 0.2279809418 -0.00338
+-0.2576578903 -0.1318002566 -0.018282
+-0.2416217956 -0.1365342795 -0.012324
+0.5692715513 0.007356680099 -0.48512
+0.3372067083 -0.3709349309 -0.167696
+0.2665947526 -0.2603896172 -0.377606
+0.280547371 -0.2719784841 -0.4422
+0.9452668958 -0.06739590871 -0.081876
+-0.1903483952 -0.1020976872 -0.002042
+-0.200944321 -0.09760347302 0.00062
+0.0744220258 -0.06939527818 0.00062
+0.2764997669 -0.3755287311 -0.192388
+-0.2200209981 0.402287399 -0.004294
+0.04175142909 -0.04374290559 0.00062
+-0.1120620526 -0.03788199169 -0.009836
+-0.1131265242 -0.6081879289 -0.002162
+-0.1068711302 -0.6003986301 0.000618
+-0.1100652437 -0.6157703052 -0.002076
+0.4287963972 0.1387944712 -0.356604
+-0.07384414215 0.1642383522 -0.011798
+-0.2762780236 -0.4734704507 -0.039618
+-0.2755042062 -0.5106036222 -0.04308
+0.3555648448 0.02220927618 -0.366504
+0.3119083249 -0.4220895052 -0.178848
+0.301765379 -0.4055091909 -0.213998
+0.2702249955 -0.600276278 0.00062
+-0.06586700745 -0.07547331616 -0.008918
+-0.03631353345 0.8346713027 -0.009718
+0.3555662335 0.03202405637 -0.354472
+0.04999521701 -0.03106987065 0.00062
+0.009718227046 0.2424670067 -0.00338
+0.04812062785 -0.0479385974 -0.00138
+-0.355607674 -0.334122866 -0.054052
+-0.3832107514 -0.3210471995 -0.106694
+-0.1222715157 0.1014079971 -0.01938
+0.03384341978 -0.04608731329 0.000592
+0.3682338979 -0.08233144453 -0.523646
+-0.4414471968 -0.4372922733 -0.140812
+0.01380574113 0.1851530327 -0.015694
+0.3543116529 -0.6079998584 -0.01358
+-0.02062331333 0.02247301734 -0.01826
+0.3058817803 -0.6505100905 -0.005288
+0.3125079905 -0.6564705582 -0.010622
+0.3717701785 -0.5689796061 -0.016756
+0.3377607328 0.07677417013 -0.177606
+0.3311528194 0.0722004943 -0.15994
+0.04960555433 -0.02195510746 0.00062
+-0.03322245221 0.8798502276 -0.03478
+0.2851015228 0.4100519146 -0.000122
+0.2827186807 0.4172188928 0.00062
+0.03472931798 0.8673486635 -0.00899
+0.2715508411 0.7643475286 -0.009148
+0.2732445121 0.774697624 -0.008742
+0.1678340908 0.005177579128 0.00062
+0.1284676168 0.03075293631 -0.040602
+-0.1352373208 -0.6974534461 -0.009046
+0.1306537121 0.00279351307 -0.048814
+-0.1331784965 -0.6858390795 -0.020186
+0.8166134553 0.02202870711 -0.070756
+0.3257799394 -0.6208953542 -0.007804
+-0.1374414393 -0.8707915581 -0.010162
+-0.1501385596 -0.8809505441 -0.027654
+-0.2202094992 -0.08231582189 -0.015378
+-0.2218365903 -0.09262179315 -0.0114
+-0.2308866605 -0.08424098332 -0.016666
+-0.1515155387 -0.5196909875 -0.00372
+-0.1922852446 0.1218021703 -0.015888
+0.1348229614 -0.005403756105 -0.037704
+0.2432153341 -0.6139597248 -0.001108
+-0.17996664 -0.107131125 -0.003304
+-0.4316684605 0.1244973028 -0.038948
+0.1288804435 0.1236526989 -0.006174
+-0.2776514943 -0.142416013 -0.024742
+-0.02169095629 0.2051233463 -0.009794
+-0.2316109174 -0.1346238436 -0.00936
+-0.06344631046 0.8654309949 -0.0815
+-0.01461157711 0.864114893 -0.027016
+0.04091918505 -0.02363432579 0.000616
+-0.3142768621 -0.06580750805 -0.044408
+0.2777693004 -0.518898241 -0.009506
+-0.2142236682 -0.6692525226 -0.107928
+-0.5810229063 0.07568011714 -0.206978
+0.7683673448 -0.1095800079 -0.045544
+0.05803384319 0.8677697418 -0.003292
+-0.2988117006 0.2551043759 -0.025158
+0.3285411122 0.6802670124 -0.017856
+0.3176951129 0.6822304473 -0.009688
+0.1015328485 0.006875717078 -0.043468
+-0.1800160245 -0.8642751105 -0.041972
+-0.1282659844 -0.5602676747 -0.00339
+0.002611081808 -0.03534539997 -0.007408
+-0.2206422046 0.206972587 -0.00393
+-0.214102197 0.2005500244 -0.008866
+-0.05775778763 0.1111898806 -0.019124
+-0.4113723407 0.1190227786 -0.031472
+-0.4093222897 0.5198722356 -0.029796
+0.1129803299 -0.03108367348 -0.030542
+0.03511234126 0.04038644033 -0.026952
+-0.6436775621 0.06251383455 -0.187958
+-0.6867519884 0.06190280429 -0.187148
+-0.6633250375 0.02235651425 -0.174274
+0.04062394118 -0.08156041638 -0.000938
+0.04098335485 -0.08329007655 -0.00221
+-0.142949489 -0.1213486393 -0.001204
+-0.152037018 -0.1167462419 -0.003284
+-0.2409873948 0.3457666408 -0.00734
+-0.2498918949 0.3399178057 -0.012494
+0.2334159268 -0.5062663109 -0.007138
+0.3092542033 0.006411709588 -0.13181
+0.03708462404 0.2274021248 -0.00538
+0.03660004264 0.2172406199 -0.008724
+-0.1308394093 -0.827198727 -0.00278
+-0.1246901459 -0.8319601417 0.00062
+0.2611049126 -0.5514942777 -0.004368
+-0.2644127018 0.4711339362 -0.006494
+0.09526290366 0.05958789302 -0.03134
+-0.1592721099 -0.08578972736 -0.005598
+-0.003818665761 -0.08773148597 0.00062
+-0.02739180786 0.8352981635 -0.009628
+-0.03860449881 -0.1440424483 -0.0029
+-0.04016585235 -0.1380753606 -0.003706
+0.3278173617 0.5866787048 -0.046018
+-0.1268829383 -0.5407931067 0.00062
+-0.2417320418 -0.4592935372 -0.028822
+0.05063846674 0.8535115159 -0.002724
+0.02789940662 -0.07113563083 0.00062
+0.03141291738 -0.06983308188 -0.004782
+0.03261290578 -0.06969419478 -0.0034
+0.07934819941 -0.03632217908 -0.00938
+0.3440757971 0.5908728849 -0.082082
+-0.1294057843 0.2322297785 0.00062
+0.1945934679 0.5848472825 -0.004516
+0.2054753964 0.5857714421 -0.007332
+0.2606843945 -0.6045389407 -0.000478
+0.03271042184 -0.05127331978 -0.006922
+0.2385211725 -0.3429305029 -0.25731
+0.2581135584 -0.2784505173 -0.398204
+0.02277836991 0.8223713543 0.000388
+-0.1667619335 0.7655310306 7.8e-05
+-0.3343005199 -0.3200281126 -0.047576
+0.5782155052 0.03036851043 -0.502794
+0.2853877619 0.3978447395 0.00062
+0.2756306141 -0.07447901024 -0.354354
+0.0425746717 -0.0381833113 0.000612
+0.2890551077 0.002738175238 -0.014742
+0.4556435731 -0.3171657819 -0.059972
+0.4454150948 -0.3402864969 -0.080054
+-0.333641621 0.577882704 -0.008122
+0.321036072 -0.1885871189 -0.500696
+-0.187537678 -0.07500898582 0.00062
+-0.1538362856 0.7923372578 -0.005168
+-0.15643226 0.7831381749 -0.000892
+0.1041376092 -0.02910704225 0.000616
+-0.1442426649 -0.1268294748 -0.000618
+0.295775947 -0.6240051675 0.00062
+0.2965736628 -0.621970671 -0.000524
+0.2981489258 -0.6228131268 -0.001346
+0.2960917238 -0.6477764126 0.00061
+-0.2113945381 -0.09225158436 0.00062
+-0.2027454952 -0.09240883526 0.00062
+-0.2046668265 -0.08966620037 0.00062
+0.2589594096 -0.6030345587 -0.00076
+0.09999127629 0.1680287591 -0.01461
+0.7001829415 -0.003942127436 -0.12407
+0.2365099748 -0.706893851 -0.002228
+0.3105843804 0.6951922673 -0.007722
+-0.2049232845 -0.834578743 -0.073214
+0.09311598757 -0.06693064872 -0.000946
+0.2736329132 0.4686089959 -0.010314
+0.04997340238 0.862665161 -0.003964
+0.04260442489 0.8558132092 -0.005156
+0.02454223165 -0.08122441959 0.00062
+0.4882149134 -0.2637052867 -0.029784
+-0.102137634 0.1498924095 -0.00938
+0.324231834 -0.5274927016 -0.016154
+-0.1981330481 -0.7121550269 -0.037652
+0.05192572119 -0.07493058719 -0.000814
+0.5059875349 -0.2971082926 -0.020286
+0.3100856899 0.2068806554 -0.005164
+0.3041509728 0.2113532179 0.000342
+0.02652223219 0.8238595403 0.00062
+-0.02356579289 0.8173343865 -0.00338
+0.3440939459 0.6613752709 -0.026628
+-0.1065422681 -0.6297487922 -0.001598
+0.04116994418 -0.0542916943 0.000616
+0.1774232321 -0.07807434932 -0.024742
+-0.2309395891 -0.6619464453 -0.118172
+-0.4453209075 0.4729392092 -0.176596
+-0.4756297112 0.4567140049 -0.234754
+0.3083684987 0.2528944593 -0.013822
+0.186381592 -0.007861775868 -0.004894
+-0.2839137536 0.5271023269 0.000298
+-0.0837633144 0.8541025288 -0.088116
+-0.07065391597 0.8511782641 -0.064114
+0.3045244607 -0.01153791937 -0.205448
+0.3082893357 -0.5861525244 -0.001982
+0.2895000942 -0.3884229247 -0.208592
+0.2543030227 -0.6798453956 -0.000764
+0.07580509532 -0.05641908776 -0.003638
+0.1413732685 0.1091946672 0.000618
+0.252921792 -0.2612181088 -0.290932
+0.0951563296 -0.002546894451 -0.019312
+-0.5514048184 0.1483705034 -0.222334
+0.09315307155 -0.05364455466 0.000618
+0.3076451607 0.4050463334 -0.03352
+-0.18968364 -0.7926774479 -0.057324
+0.2794124232 -0.6599537741 -0.00249
+0.03931327639 -0.01515969624 -0.00683
+-0.03718336885 0.1287639007 -0.019314
+0.03194298927 -0.07150615218 0.00062
+0.02988512587 -0.07088664927 -0.00344
+0.0884684679 -0.03389098957 -0.003694
+-0.216277602 0.1887220463 -0.014776
+0.3172871554 0.4682126632 -0.105094
+0.299901165 0.413538641 -0.016706
+0.09648108398 0.0832880624 -0.025892
+0.1543239901 0.04218723152 0.00032
+0.8563066498 -0.1966486964 -0.126768
+-0.4715368918 0.1614805283 -0.048444
+0.03016855047 0.8317468682 -0.001104
+0.6384747675 -0.1419186326 -0.070164
+0.6158008374 -0.1348066945 -0.089154
+0.6318767753 -0.1170205066 -0.083668
+0.1334431125 0.1047646954 -0.007046
+0.06441618225 -0.07337734258 -0.003186
+0.06477310585 -0.07432456789 -0.004998
+-0.148383043 -0.5815297282 -0.018104
+0.1827097513 -0.3247542729 0.00062
+0.2086099918 -0.02040843496 -0.027934
+0.2228145689 -0.2604115014 -0.14953
+0.2593158035 -0.6019645966 -0.001578
+0.231751549 0.6723574075 -0.003532
+0.3090677342 -0.4848835168 -0.097266
+0.04496648747 -0.01457165123 0.000598
+0.2771384629 0.7322682404 -0.005752
+0.2292840855 -0.4814382919 -0.0094
+0.2408520472 -0.476432193 -0.009554
+0.1219206501 -0.06748226521 -0.018712
+0.04811492818 -0.02305717122 0.00062
+0.04751080616 -0.02967365541 -0.000924
+0.04810356935 -0.01753627591 0.00062
+0.06721762466 0.9430502049 0.000468
+0.06547617827 0.9352061742 -0.004242
+0.09140970383 -0.07715987291 -0.00138
+0.1518776891 0.005291400371 0.00062
+0.1486248434 0.01582492566 0.000612
+0.03197982277 -0.06006880437 -0.004064
+0.3643967677 0.4401382198 -0.27789
+-0.140816185 -0.8790805313 -0.012528
+0.3507524747 0.6744866632 -0.029884
+0.06662877117 0.04155163517 -0.02852
+0.6023957555 -0.1113250557 -0.101158
+0.02802464972 0.2005712131 -0.01291
+0.04037124868 -0.03921893287 -0.00338
+-0.4500866886 0.110616432 -0.085152
+-0.02112224752 0.8273239067 -0.002674
+-0.1577068431 0.1919517395 -0.006238
+-0.213415555 0.1435686474 -0.018382
+-0.004526764991 -0.01061645511 0.00062
+0.1053024341 -0.002666867297 -0.033476
+0.08764627781 -0.02818581211 -0.005068
+0.05279648885 -0.07466325045 0.000618
+-0.101529221 -0.6326219515 0.00062
+-0.1030383458 -0.6375632782 0.000618
+0.2503689698 -0.5935762556 -0.002356
+0.2532696958 -0.5907527289 -0.0029
+0.4405248182 0.3306353814 -0.40119
+0.1383335384 0.1203689532 0.00043
+-0.1689214987 0.04306505875 -0.01587
+0.2706150266 -0.54243538 -0.004112
+-0.1978380954 -0.5594403448 -0.03367
+-0.186386268 -0.8449762326 -0.03938
+-0.352084602 -0.1492735542 -0.057698
+0.5613710226 0.3380639445 -0.584808
+-0.2402665274 -0.00280300831 -0.021644
+0.04152635543 -0.04111994287 0.00062
+-0.3437809851 0.3176745548 -0.025486
+0.3058707453 -0.6652450342 -0.008772
+0.2027536322 -0.1229509749 -0.023824
+0.2400847093 -0.2697315999 -0.269428
+0.05755854097 0.8769802892 -0.00442
+0.6670168411 -0.152592518 -0.05731
+0.2682038688 -0.5964469888 0.00062
+0.0367498297 -0.04222727189 -0.003846
+0.07579001378 -0.0367757233 -0.003678
+0.07722501422 -0.03456475955 0.00059
+-0.1895589428 0.03706727579 -0.018512
+-0.2619249463 -0.2747066574 -0.02529
+-0.1440833753 -0.6221993704 -0.025352
+0.06654353493 -0.06886854905 0.000616
+0.3207612423 -0.4053145588 -0.137734
+0.3226340113 0.01874026756 -0.174586
+0.02810632177 -0.05598392532 -0.002912
+-0.1467003438 -0.5129182002 0.000618
+0.5818325124 -0.04547975512 -0.23527
+-0.09652456707 -0.1293407123 0.00062
+0.1855853363 -0.2586773433 0.00028
+-0.005883544304 -0.00873948554 0.00062
+0.0848447216 0.06477879811 -0.029528
+0.06989823211 0.9467958374 0.00057
+0.4632507783 -0.527096565 -0.104598
+0.5077774593 -0.3221452742 -0.026364
+0.3080435478 0.0288208147 -0.031246
+0.3015166385 0.03210979422 -0.008612
+0.2245468262 0.6782671904 0.00062
+-0.203371217 -0.07845398292 -0.006954
+-0.2123824367 -0.08488554639 -0.011442
+0.8301268445 -0.2197819956 -0.097786
+-0.2689524151 0.2294435555 -0.017526
+-0.2810996544 0.2355113367 -0.022642
+-0.09853186425 -0.1272583172 0.00062
+0.7868864978 -0.1466076673 -0.05848
+-0.2142506193 0.3627271954 -0.00284
+0.02203408904 0.8199020459 0.00062
+-0.3838875605 0.5760738079 -0.013532
+0.025536231 -0.06467638724 -0.00062
+-0.9571774338 0.06153780101 -0.217624
+-0.2434740056 0.4335663939 -0.00679
+0.476530925 -0.310342786 -0.028472
+0.3037476956 0.7385267878 -0.008394
+-0.2595065709 -0.1773011202 -0.012244
+-0.1996790605 -0.7335139906 -0.032958
+0.3375999122 0.0876443909 -0.172108
+0.09374012664 -0.05277835761 0.00062
+-0.1915005353 -0.6887665272 -0.109852
+0.3380197384 0.3635745685 -0.134988
+-0.4838208927 0.144656978 -0.137664
+0.3276456083 -0.6514123019 -0.013314
+0.09260678638 -0.07911230684 -0.00138
+-0.1603150644 0.7888417137 -0.003624
+-0.3127491068 0.5796785102 0.000616
+0.09079560143 -0.07929570514 -0.00138
+0.1493859855 0.04554550704 0.00022
+-0.0809475741 -0.1420833644 -0.002932
+-0.02984579286 -0.05409617525 -0.009266
+-0.2863551138 -0.1818493535 -0.026148
+0.02216632246 0.843410111 -0.006418
+0.2911826814 -0.6191661059 -0.000434
+-0.267671909 -0.2020969175 -0.02086
+-0.2922862748 -0.2201777693 -0.03158
+0.08813194141 -0.07245941987 -0.001278
+0.0380905417 -0.04487148608 -0.00338
+0.2723774893 -0.6025267737 0.00062
+0.6454768869 -0.2360971106 -0.073304
+0.05574957137 0.02430491211 -0.019422
+0.3459532784 0.1476323196 -0.073406
+0.02476638451 -0.08617770131 -0.000296
+0.4682441879 -0.3593250837 -0.070772
+0.582587607 -0.3066286467 -0.044662
+0.4977461004 -0.3103760974 -0.025082
+0.3307076074 -0.5957369882 -0.01269
+-0.2172294515 0.3524802031 -0.002708
+-0.2513980596 0.4360215733 -0.008212
+0.2802366548 0.7589948855 -0.008962
+-0.02992725647 0.01645701598 -0.021114
+0.04480605861 0.9261731277 -0.019546
+0.2634732173 -0.004667537868 -0.008804
+0.2987115177 -0.6259334595 -0.00138
+0.3015163185 -0.627710613 -0.000976
+0.03184897597 -0.07686929434 -0.00083
+0.02372658213 -0.006512551459 0.000618
+0.09584589354 -0.04431046804 -0.000922
+-0.1413810939 -0.7467794738 -0.009216
+-0.1168312425 0.05692243093 -0.01561
+0.4448915351 0.134304281 -0.460644
+0.3465475143 0.08049923305 -0.222938
+0.01850981119 -0.02546532708 -0.002098
+-0.2706922807 -0.1827612373 -0.020836
+0.1013493369 -0.009212133344 -0.02012
+0.3127030805 0.2157548834 -0.007032
+0.2973679838 -0.2888127019 -0.375302
+-0.1361717502 -0.7553815219 -0.007132
+0.2721107393 -0.6007338438 -0.00039
+0.2275060131 -0.49012304 -0.008862
+0.4506690818 0.1809036396 -0.408618
+0.1853590541 -0.1958998175 -0.009072
+-0.159819949 -0.3874550907 -0.002856
+-0.2209034649 0.02649095341 -0.021026
+-0.01765860301 -0.02906963667 0.00062
+-0.01622645105 -0.02919878792 -0.000422
+-0.3419906797 -0.06700513903 -0.053992
+0.3570509193 0.08314458858 -0.249562
+0.04466252686 0.2329482951 -0.005302
+-0.08245867723 0.03807288804 -0.015166
+0.1058106386 0.1590444691 -0.011082
+0.1838042925 -0.06485631316 -0.094986
+0.3102320352 -0.09813463778 -0.497934
+-0.1683172266 -0.05810379415 -0.008196
+0.2253487677 0.6535232732 -0.004738
+-0.3998324735 -0.431029851 -0.112898
+0.7618146439 0.08353964307 -0.235308
+0.06090959937 -0.05875218301 0.00062
+0.1691260366 -0.06518879965 -0.04432
+-0.3202987186 0.4355643958 -0.017238
+0.005528849684 -0.05553705348 -0.00344
+0.2289870874 -0.4725736453 -0.008868
+0.4436988378 0.1554713789 -0.352264
+0.2273586409 0.5418776021 -0.003614
+-0.1578633327 -0.6691396404 -0.035642
+-0.3272781504 0.1631921958 -0.025194
+0.1083179799 -0.07990230167 -0.006282
+-0.112968104 -0.1130120962 0.00062
+0.2485194848 0.7624335733 0.000578
+0.2843268731 0.3670374076 0.00062
+0.04773485752 -0.02102958272 -0.000882
+-0.8303241215 0.002946012497 -0.162182
+-0.1859530901 -0.2923319133 -0.007736
+0.0001335604387 -0.03789519366 0.00062
+0.4712638517 -0.333628065 -0.063876
+0.0359590786 -0.04625428292 -0.004336
+0.02702738276 -0.08104699156 -0.000376
+0.04314107262 -0.08455136524 0.000138
+1 2
+3 2
+3 1
+4 5
+6 4
+6 5
+7 8
+9 7
+9 8
+10 11
+12 11
+12 10
+13 14
+15 14
+15 13
+16 17
+16 18
+17 18
+19 20
+19 21
+20 21
+22 23
+24 23
+24 22
+25 26
+25 27
+26 27
+28 29
+30 29
+30 28
+31 32
+31 33
+33 32
+34 35
+36 34
+36 35
+37 38
+39 37
+39 38
+40 41
+42 41
+42 40
+43 44
+45 44
+45 43
+46 47
+46 48
+48 47
+49 50
+51 49
+51 50
+52 53
+52 54
+53 54
+55 56
+57 56
+57 55
+58 59
+60 58
+60 59
+61 62
+61 63
+62 63
+64 65
+66 64
+66 65
+67 68
+69 68
+69 67
+70 71
+72 70
+72 71
+73 74
+73 75
+74 75
+76 77
+78 76
+78 77
+79 80
+81 80
+81 79
+82 83
+82 84
+83 84
+85 86
+87 86
+87 85
+88 89
+88 90
+90 89
+91 92
+93 91
+93 92
+94 95
+96 94
+96 95
+97 98
+99 98
+99 97
+100 101
+102 100
+102 101
+103 104
+105 103
+105 104
+106 107
+106 108
+107 108
+109 110
+109 111
+110 111
+112 113
+114 113
+114 112
+115 116
+117 116
+117 115
+118 119
+118 120
+120 119
+121 122
+121 123
+122 123
+124 125
+126 124
+126 125
+127 128
+129 128
+129 127
+130 131
+132 131
+132 130
+133 134
+135 133
+135 134
+136 137
+138 136
+138 137
+139 140
+141 140
+141 139
+142 143
+144 143
+144 142
+145 146
+147 146
+147 145
+148 149
+150 149
+150 148
+151 152
+151 153
+152 153
+154 155
+156 154
+156 155
+157 158
+159 157
+159 158
+160 161
+160 162
+161 162
+163 164
+163 165
+164 165
+166 167
+166 168
+167 168
+169 170
+171 170
+171 169
+172 173
+174 172
+174 173
+175 176
+175 177
+176 177
+178 179
+180 178
+180 179
+181 182
+181 183
+183 182
+184 185
+186 185
+186 184
+187 188
+189 188
+189 187
+190 164
+191 164
+191 190
+192 193
+192 194
+194 193
+195 196
+197 196
+197 195
+198 199
+200 199
+200 198
+201 202
+203 202
+203 201
+204 205
+204 206
+205 206
+207 208
+209 207
+209 208
+210 211
+212 211
+212 210
+213 214
+213 215
+214 215
+216 217
+216 218
+217 218
+219 220
+221 219
+221 220
+222 223
+224 222
+224 223
+225 226
+225 227
+226 227
+228 229
+230 228
+230 229
+231 158
+231 157
+232 233
+232 234
+233 234
+235 236
+237 236
+237 235
+238 239
+240 238
+240 239
+241 242
+243 241
+243 242
+244 245
+244 246
+246 245
+247 248
+249 247
+249 248
+250 251
+252 251
+252 250
+253 254
+255 253
+255 254
+256 257
+256 258
+257 258
+259 260
+261 260
+261 259
+262 263
+264 262
+264 263
+265 266
+265 267
+267 266
+268 269
+268 270
+269 270
+271 22
+271 23
+272 273
+272 274
+273 274
+275 276
+275 277
+277 276
+278 279
+280 279
+280 278
+281 282
+283 282
+283 281
+284 285
+286 285
+286 284
+159 287
+288 287
+288 159
+289 290
+291 290
+291 289
+292 293
+294 293
+294 292
+46 295
+296 295
+296 46
+297 298
+299 298
+299 297
+300 301
+302 301
+302 300
+303 304
+305 304
+305 303
+257 306
+258 306
+307 308
+307 309
+309 308
+310 311
+310 312
+312 311
+313 314
+315 314
+315 313
+316 317
+316 318
+317 318
+319 320
+321 320
+321 319
+322 323
+322 324
+323 324
+325 326
+325 327
+327 326
+328 329
+330 329
+330 328
+331 332
+333 331
+333 332
+334 335
+336 334
+336 335
+337 338
+339 338
+339 337
+340 341
+340 342
+341 342
+343 242
+344 242
+344 343
+345 346
+345 347
+346 347
+348 349
+350 348
+350 349
+351 352
+353 351
+353 352
+314 354
+355 314
+355 354
+356 357
+356 358
+358 357
+359 360
+359 361
+360 361
+362 363
+364 363
+364 362
+365 366
+365 367
+367 366
+368 369
+370 368
+370 369
+371 372
+371 373
+372 373
+374 375
+376 375
+376 374
+377 378
+379 378
+379 377
+380 381
+380 382
+381 382
+383 384
+385 383
+385 384
+386 131
+386 387
+131 387
+388 389
+388 390
+389 390
+391 392
+393 391
+393 392
+394 395
+396 394
+396 395
+397 398
+397 399
+398 399
+400 401
+402 401
+402 400
+403 404
+405 404
+405 403
+406 407
+408 406
+408 407
+206 409
+205 409
+410 227
+411 410
+411 227
+412 413
+414 412
+414 413
+415 416
+417 416
+417 415
+418 419
+418 420
+420 419
+421 422
+423 421
+423 422
+424 425
+424 426
+425 426
+427 428
+429 427
+429 428
+430 431
+432 431
+432 430
+433 408
+433 434
+408 434
+435 436
+437 435
+437 436
+438 439
+440 438
+440 439
+441 442
+443 441
+443 442
+444 445
+446 444
+446 445
+447 448
+449 448
+449 447
+450 451
+450 452
+452 451
+453 145
+454 145
+454 453
+455 456
+457 456
+457 455
+458 459
+458 460
+460 459
+461 462
+461 463
+463 462
+464 465
+466 464
+466 465
+159 467
+288 467
+468 469
+468 470
+470 469
+471 472
+473 471
+473 472
+474 475
+364 474
+364 475
+476 477
+478 476
+478 477
+479 425
+480 425
+480 479
+481 482
+483 482
+483 481
+54 484
+52 484
+485 486
+485 487
+487 486
+488 489
+490 488
+490 489
+491 492
+491 493
+492 493
+494 495
+494 328
+328 495
+496 497
+496 410
+497 410
+498 499
+500 498
+500 499
+501 502
+503 502
+503 501
+504 505
+504 506
+505 506
+507 508
+509 507
+509 508
+510 511
+512 510
+512 511
+513 514
+515 514
+515 513
+516 189
+516 187
+517 518
+517 519
+519 518
+520 521
+522 520
+522 521
+523 524
+523 525
+525 524
+526 527
+528 527
+528 526
+529 530
+292 529
+292 530
+531 532
+531 533
+532 533
+534 535
+536 534
+536 535
+537 538
+539 538
+539 537
+540 541
+540 508
+508 541
+542 543
+542 532
+543 532
+544 545
+546 544
+546 545
+547 548
+547 549
+548 549
+550 551
+552 551
+552 550
+553 59
+554 553
+554 59
+555 556
+555 513
+556 513
+557 558
+557 559
+558 559
+140 560
+139 560
+396 561
+562 396
+562 561
+563 564
+563 565
+565 564
+134 566
+567 134
+567 566
+568 569
+568 570
+570 569
+571 572
+571 573
+572 573
+574 575
+574 576
+575 576
+577 578
+579 577
+579 578
+580 581
+321 580
+321 581
+582 583
+584 582
+584 583
+585 586
+585 587
+587 586
+588 589
+590 589
+590 588
+591 592
+593 591
+593 592
+594 595
+596 595
+596 594
+597 598
+597 599
+598 599
+600 601
+602 600
+602 601
+603 604
+603 605
+605 604
+606 251
+607 606
+607 251
+608 609
+610 608
+610 609
+611 612
+613 611
+613 612
+614 489
+614 488
+615 616
+617 615
+617 616
+618 619
+620 619
+620 618
+621 80
+621 622
+80 622
+623 624
+623 625
+624 625
+626 383
+626 627
+383 627
+628 629
+630 628
+630 629
+631 632
+631 633
+632 633
+634 635
+634 636
+636 635
+637 638
+639 638
+639 637
+640 641
+640 642
+641 642
+643 644
+643 645
+645 644
+646 647
+648 647
+648 646
+649 650
+526 650
+526 649
+651 652
+653 652
+653 651
+654 655
+656 654
+656 655
+657 658
+659 657
+659 658
+660 661
+662 660
+662 661
+663 664
+665 664
+665 663
+666 667
+668 667
+668 666
+669 670
+671 669
+671 670
+14 672
+13 672
+673 674
+675 673
+675 674
+676 677
+678 677
+678 676
+679 680
+272 680
+272 679
+91 681
+91 682
+681 682
+683 684
+683 685
+685 684
+686 687
+688 686
+688 687
+689 690
+476 689
+476 690
+691 692
+693 692
+693 691
+694 695
+694 696
+696 695
+697 698
+697 699
+698 699
+700 260
+701 260
+701 700
+702 703
+704 703
+704 702
+705 706
+707 706
+707 705
+58 708
+60 708
+405 709
+405 710
+709 710
+711 712
+713 712
+713 711
+714 715
+714 716
+715 716
+717 718
+719 717
+719 718
+720 721
+722 720
+722 721
+723 724
+725 723
+725 724
+726 727
+726 728
+727 728
+183 729
+183 417
+417 729
+730 731
+730 732
+731 732
+733 734
+427 733
+427 734
+735 47
+735 736
+736 47
+276 737
+275 737
+738 739
+738 740
+740 739
+741 742
+743 741
+743 742
+744 745
+744 746
+746 745
+747 748
+363 748
+363 747
+367 749
+365 749
+750 325
+751 325
+751 750
+752 332
+753 752
+753 332
+730 754
+730 755
+754 755
+756 757
+301 757
+301 756
+758 759
+760 758
+760 759
+761 762
+763 762
+763 761
+764 765
+764 766
+765 766
+767 768
+767 570
+570 768
+769 770
+417 770
+417 769
+771 772
+771 773
+772 773
+774 556
+774 555
+775 776
+777 776
+777 775
+778 779
+582 778
+582 779
+780 781
+21 780
+21 781
+782 464
+783 782
+783 464
+784 785
+786 785
+786 784
+787 788
+789 787
+789 788
+790 791
+792 790
+792 791
+50 793
+50 794
+794 793
+795 590
+795 507
+590 507
+796 797
+798 796
+798 797
+799 800
+799 801
+800 801
+802 803
+804 802
+804 803
+805 806
+807 806
+807 805
+6 808
+808 4
+809 810
+809 811
+811 810
+812 813
+814 813
+814 812
+576 815
+816 815
+816 576
+817 818
+817 819
+818 819
+820 821
+822 821
+822 820
+823 824
+825 824
+825 823
+826 827
+828 827
+828 826
+829 830
+829 831
+831 830
+832 833
+834 833
+834 832
+745 835
+836 745
+836 835
+837 838
+839 838
+839 837
+840 841
+842 840
+842 841
+617 843
+844 843
+844 617
+190 845
+163 845
+163 190
+846 847
+846 848
+847 848
+849 337
+850 849
+850 337
+851 56
+851 57
+852 853
+852 854
+853 854
+855 856
+711 855
+711 856
+857 858
+859 857
+859 858
+860 348
+861 860
+861 348
+862 863
+864 863
+864 862
+865 866
+865 867
+866 867
+826 868
+826 869
+869 868
+870 871
+870 872
+872 871
+97 343
+98 343
+873 874
+873 246
+246 874
+875 876
+875 877
+877 876
+878 879
+880 878
+880 879
+881 811
+882 811
+882 881
+883 884
+883 885
+885 884
+886 887
+888 887
+888 886
+504 448
+448 506
+889 890
+889 891
+891 890
+391 892
+893 391
+893 892
+894 895
+894 896
+895 896
+72 897
+72 898
+898 897
+899 900
+899 901
+901 900
+902 903
+902 904
+904 903
+905 906
+907 906
+907 905
+908 909
+910 908
+910 909
+911 912
+913 911
+913 912
+914 383
+914 626
+915 916
+915 917
+916 917
+396 918
+396 919
+919 918
+593 920
+920 592
+921 922
+615 921
+615 922
+923 924
+925 924
+925 923
+926 927
+928 927
+928 926
+929 930
+931 930
+931 929
+920 932
+933 920
+933 932
+934 935
+936 934
+936 935
+937 780
+938 937
+938 780
+813 939
+812 939
+615 843
+615 940
+843 940
+750 941
+751 941
+942 943
+942 482
+943 482
+944 945
+946 944
+946 945
+947 948
+947 949
+949 948
+950 951
+952 950
+952 951
+111 953
+954 111
+954 953
+955 956
+957 956
+957 955
+958 959
+958 960
+960 959
+961 962
+961 963
+962 963
+964 965
+964 966
+965 966
+967 968
+969 968
+969 967
+970 479
+970 425
+971 972
+971 973
+972 973
+974 975
+542 975
+542 974
+976 977
+978 976
+978 977
+592 979
+591 979
+980 981
+982 980
+982 981
+983 984
+985 984
+985 983
+986 987
+264 987
+264 986
+988 989
+988 990
+989 990
+991 992
+991 993
+993 992
+994 767
+994 995
+767 995
+88 996
+997 88
+997 996
+998 999
+1000 999
+1000 998
+1001 924
+1002 924
+1002 1001
+1003 1004
+1005 1004
+1005 1003
+1006 1007
+1006 252
+252 1007
+473 1008
+473 1009
+1008 1009
+179 1010
+178 1010
+1011 1012
+1011 741
+1012 741
+1013 1014
+1013 1015
+1014 1015
+1016 1017
+1016 1018
+1018 1017
+1019 1020
+1021 1019
+1021 1020
+1022 530
+1022 529
+1023 1024
+1025 1024
+1025 1023
+1026 1027
+1026 1028
+1027 1028
+1029 1030
+1029 1031
+1031 1030
+1032 304
+1033 1032
+1033 304
+1034 1035
+1034 1036
+1035 1036
+1037 1038
+1039 1038
+1039 1037
+1040 1041
+1040 1042
+1041 1042
+171 252
+171 1007
+1043 1044
+1043 684
+1044 684
+1045 1046
+1047 1046
+1047 1045
+1048 513
+556 1048
+1049 1050
+1051 1049
+1051 1050
+1052 1053
+1054 1053
+1054 1052
+1055 1056
+1055 953
+1056 953
+106 1057
+1058 106
+1058 1057
+1059 1060
+1061 1059
+1061 1060
+1062 1063
+1064 1062
+1064 1063
+1065 1066
+1067 1066
+1067 1065
+1068 1069
+1068 1070
+1069 1070
+1071 1072
+1073 1071
+1073 1072
+1074 1075
+1074 1076
+1075 1076
+1077 1078
+1079 1078
+1079 1077
+1080 282
+283 1080
+1081 945
+1081 1082
+1082 945
+1083 1084
+1085 1084
+1085 1083
+1086 669
+1086 671
+1087 1088
+245 1087
+245 1088
+1089 1090
+1091 1090
+1091 1089
+248 682
+249 682
+1092 1093
+1094 1092
+1094 1093
+1095 1096
+1097 1095
+1097 1096
+1098 973
+972 1098
+1099 884
+1100 884
+1100 1099
+1101 767
+1101 994
+1102 1103
+1104 1102
+1104 1103
+1105 1106
+1107 1105
+1107 1106
+1108 1109
+1110 1109
+1110 1108
+1111 1112
+1111 1113
+1112 1113
+1114 1115
+1116 1114
+1116 1115
+1117 1118
+1119 1118
+1119 1117
+1120 1121
+1120 1122
+1121 1122
+1123 1048
+1123 556
+1124 1125
+1126 1125
+1126 1124
+1127 1128
+1129 1127
+1129 1128
+1130 1131
+1132 1130
+1132 1131
+1133 1134
+1135 1133
+1135 1134
+1136 1137
+982 1136
+982 1137
+1138 1043
+1138 1139
+1139 1043
+1140 1141
+1142 1140
+1142 1141
+1143 1144
+1143 1145
+1145 1144
+1146 1147
+1148 1147
+1148 1146
+1149 1150
+1151 1150
+1151 1149
+1152 1153
+1152 1141
+1153 1141
+1154 905
+1154 906
+1155 1156
+1157 1155
+1157 1156
+1158 1159
+1158 1160
+1159 1160
+1161 1162
+1163 1161
+1163 1162
+1164 1165
+1166 1165
+1166 1164
+784 489
+786 489
+1167 1168
+1169 1168
+1169 1167
+1170 1171
+1170 1172
+1172 1171
+1173 580
+1173 319
+319 580
+1174 1175
+1174 213
+1175 213
+1176 1177
+1178 1177
+1178 1176
+1179 1180
+1181 1180
+1181 1179
+1182 1183
+1182 1184
+1183 1184
+1185 1186
+1187 1186
+1187 1185
+1188 1189
+1188 1190
+1190 1189
+1097 1191
+1097 1192
+1192 1191
+978 1193
+978 352
+352 1193
+1194 952
+1194 951
+1195 598
+1195 597
+1196 1197
+1198 1196
+1198 1197
+1199 1200
+1199 1201
+1200 1201
+1202 1203
+1202 401
+1203 401
+1204 601
+1205 1204
+1205 601
+1206 1207
+1208 1207
+1208 1206
+1209 1210
+1209 1211
+1211 1210
+1212 1213
+344 1213
+344 1212
+1214 338
+1215 1214
+1215 338
+1216 1217
+1216 1218
+1218 1217
+1219 1059
+1219 1061
+1220 1221
+1222 1221
+1222 1220
+1223 1224
+1223 756
+1224 756
+1225 1226
+1227 1226
+1227 1225
+1228 289
+1228 290
+1229 1230
+5 1229
+5 1230
+1231 1232
+1233 1231
+1233 1232
+1234 912
+913 1234
+1235 1177
+1235 1236
+1177 1236
+1237 776
+1237 1238
+1238 776
+1239 1240
+1006 1239
+1006 1240
+1241 1242
+1243 1241
+1243 1242
+1244 1245
+1246 1245
+1246 1244
+1247 1248
+1247 1249
+1248 1249
+1250 1251
+1252 1251
+1252 1250
+888 1253
+888 1254
+1254 1253
+919 561
+1255 1256
+1257 1255
+1257 1256
+1258 1259
+1260 1258
+1260 1259
+333 1261
+1262 1261
+1262 333
+1263 1264
+1265 1264
+1265 1263
+1266 1137
+1267 1266
+1267 1137
+1268 1269
+1268 1270
+1269 1270
+1271 1272
+1273 1271
+1273 1272
+1274 883
+1275 883
+1275 1274
+1276 1277
+72 1277
+72 1276
+1278 1279
+1278 1280
+1280 1279
+1065 1281
+1066 1281
+1282 1283
+1284 1282
+1284 1283
+1285 1286
+1285 1287
+1286 1287
+1288 1289
+843 1289
+843 1288
+777 1290
+776 1290
+1291 165
+1291 1292
+1292 165
+1293 1294
+864 1293
+864 1294
+1295 1087
+1296 1295
+1296 1087
+631 1297
+1297 632
+1298 1299
+1298 1300
+1300 1299
+1301 533
+1302 1301
+1302 533
+104 1303
+1304 1303
+1304 104
+1305 1306
+450 1305
+450 1306
+1307 1249
+1247 1307
+1308 1309
+1308 1310
+1309 1310
+1311 1312
+1311 1313
+1313 1312
+955 578
+579 955
+1314 1315
+1316 1315
+1316 1314
+1317 1318
+1319 1317
+1319 1318
+1320 1321
+1322 1320
+1322 1321
+1323 1324
+1323 1325
+1324 1325
+64 1326
+64 1327
+1326 1327
+1328 1329
+1330 1328
+1330 1329
+1331 1332
+1333 1331
+1333 1332
+1334 1335
+1336 1335
+1336 1334
+1337 1338
+224 1337
+224 1338
+1339 493
+1340 493
+1340 1339
+402 1341
+402 3
+3 1341
+1342 1343
+1344 1342
+1344 1343
+1345 1346
+1345 1347
+1346 1347
+1348 775
+111 1348
+111 775
+1349 651
+1349 652
+1350 1351
+1352 1351
+1352 1350
+1324 1353
+1354 1324
+1354 1353
+1355 1356
+1355 1357
+1356 1357
+909 1358
+908 1358
+1359 1360
+1361 1360
+1361 1359
+1362 1363
+1362 1364
+1363 1364
+1365 1366
+1274 1366
+1274 1365
+454 1367
+454 368
+368 1367
+1368 1369
+1370 1369
+1370 1368
+1371 1372
+1373 1371
+1373 1372
+1374 1150
+1374 1375
+1375 1150
+507 1376
+1377 507
+1377 1376
+1378 1379
+584 1379
+584 1378
+1380 1381
+1380 1133
+1381 1133
+385 1382
+384 1382
+1292 1383
+1291 1383
+297 1384
+298 1384
+1385 1386
+1387 1386
+1387 1385
+595 1388
+596 1388
+1111 1389
+594 1111
+594 1389
+66 1390
+66 1391
+1391 1390
+1392 1393
+1392 1394
+1393 1394
+1395 1396
+1397 1396
+1397 1395
+814 1398
+814 1399
+1398 1399
+1190 1400
+1188 1400
+1401 399
+1402 399
+1402 1401
+1403 1327
+1404 1403
+1404 1327
+1405 1406
+1407 1405
+1407 1406
+1408 1409
+1408 1257
+1257 1409
+1410 1411
+1410 1412
+1411 1412
+1413 1414
+1415 1414
+1415 1413
+1416 1417
+1416 347
+347 1417
+873 528
+528 246
+1418 1419
+1420 1418
+1420 1419
+1421 1422
+1423 1422
+1423 1421
+1424 1425
+1424 1426
+1425 1426
+1427 1428
+1429 1428
+1429 1427
+1430 1431
+1432 1431
+1432 1430
+1433 1434
+1104 1434
+1104 1433
+1435 1436
+1437 1435
+1437 1436
+1438 1439
+1440 1439
+1440 1438
+1441 797
+1441 796
+1442 1443
+1444 1443
+1444 1442
+1445 1078
+1446 1445
+1446 1078
+308 1447
+309 1447
+620 848
+619 848
+847 619
+1448 1245
+1449 1245
+1449 1448
+1450 653
+1451 1450
+1451 653
+587 1452
+587 1453
+1453 1452
+647 1454
+1455 1454
+1455 647
+1456 1457
+1458 1456
+1458 1457
+320 1459
+1460 320
+1460 1459
+1461 1462
+1461 1463
+1463 1462
+1464 1465
+1466 1464
+1466 1465
+1467 1468
+1467 1469
+1469 1468
+1470 1471
+1472 1470
+1472 1471
+1473 1474
+1475 1473
+1475 1474
+1476 1477
+1476 1478
+1478 1477
+104 1479
+1480 104
+1480 1479
+1481 1028
+1026 1481
+1482 693
+1482 691
+1483 1484
+1483 1260
+1260 1484
+1485 641
+1486 641
+1486 1485
+1487 717
+1488 717
+1488 1487
+1489 1490
+1387 1490
+1387 1489
+1491 1492
+1491 1493
+1493 1492
+1494 1495
+1494 1496
+1495 1496
+1419 1497
+1498 1419
+1498 1497
+1499 1500
+1501 1500
+1501 1499
+1502 1503
+1502 1504
+1504 1503
+1505 1506
+1507 1505
+1507 1506
+1508 1422
+1509 1508
+1509 1422
+49 1510
+49 1511
+1511 1510
+1512 1513
+1514 1512
+1514 1513
+1515 1516
+1517 1516
+1517 1515
+1518 1519
+1518 1520
+1520 1519
+1521 1522
+1523 1521
+1523 1522
+1524 1525
+947 1524
+947 1525
+1526 1527
+1528 1526
+1528 1527
+240 1529
+1530 1529
+1530 240
+1531 1532
+531 1531
+531 1532
+1533 1534
+1535 1533
+1535 1534
+1536 1537
+1538 1537
+1538 1536
+1539 1270
+1268 1539
+1049 1540
+1541 1540
+1541 1049
+126 790
+790 125
+1542 1543
+1542 1544
+1543 1544
+1545 1546
+1547 1545
+1547 1546
+1548 459
+1549 459
+1549 1548
+388 1550
+388 1551
+1551 1550
+19 781
+1552 1553
+1552 1554
+1553 1554
+853 1555
+1555 854
+1556 156
+1556 155
+1557 1558
+1557 1559
+1559 1558
+1560 1561
+1562 1561
+1562 1560
+842 1563
+840 1563
+1564 1565
+1566 1564
+1566 1565
+1567 1568
+1569 1568
+1569 1567
+1570 1571
+1572 1570
+1572 1571
+1573 356
+1574 356
+1574 1573
+1575 1232
+1576 1232
+1576 1575
+90 1577
+88 1577
+1578 1579
+1578 80
+80 1579
+1580 1581
+1580 1189
+1581 1189
+1582 1583
+1584 1583
+1584 1582
+1585 1586
+1587 1585
+1587 1586
+1588 1589
+1588 1590
+1590 1589
+1591 1592
+1591 416
+1592 416
+1593 1017
+1594 1593
+1594 1017
+1595 1596
+1597 1595
+1597 1596
+1598 1599
+1600 1598
+1600 1599
+1601 559
+1601 102
+102 559
+1602 1603
+1604 1602
+1604 1603
+1579 622
+1605 1606
+1607 1606
+1607 1605
+933 1608
+1609 1608
+1609 933
+1610 357
+356 1610
+116 1501
+115 1501
+1580 1611
+1580 1612
+1612 1611
+559 1613
+557 1613
+1614 1615
+1165 1615
+1165 1614
+1616 1617
+1618 1617
+1618 1616
+1619 1620
+1621 1620
+1621 1619
+1622 1623
+1624 1623
+1624 1622
+1594 1625
+1594 1626
+1626 1625
+1627 1628
+1629 1627
+1629 1628
+1630 1067
+1630 1065
+1130 1631
+1632 1130
+1632 1631
+1633 881
+1633 811
+1634 1635
+1634 733
+733 1635
+1636 973
+971 1636
+1637 654
+1637 656
+1638 1639
+1638 1640
+1640 1639
+13 752
+15 752
+1641 1642
+1643 1642
+1643 1641
+1644 1645
+1644 1646
+1646 1645
+1647 1366
+1648 1366
+1648 1647
+1649 1650
+1649 1651
+1651 1650
+1652 1653
+1654 1652
+1654 1653
+1655 697
+1655 699
+1450 1656
+1451 1656
+1657 1658
+1657 248
+1658 248
+1659 1660
+1661 1660
+1661 1659
+1662 874
+873 1662
+1663 922
+1664 1663
+1664 922
+1665 35
+1666 35
+1666 1665
+1667 1668
+1669 1668
+1669 1667
+385 627
+1670 1671
+1154 1670
+1154 1671
+1672 1673
+1674 1672
+1674 1673
+820 1675
+1676 820
+1676 1675
+1677 155
+154 1677
+1678 1679
+1680 1679
+1680 1678
+1222 1681
+1222 1682
+1681 1682
+1683 1684
+436 1683
+436 1684
+1685 1686
+1687 1686
+1687 1685
+1688 1689
+1690 1688
+1690 1689
+1691 1692
+1691 1693
+1693 1692
+1694 1151
+1120 1151
+1120 1694
+708 1499
+76 1499
+76 708
+1695 1696
+1697 1695
+1697 1696
+461 1183
+1698 461
+1698 1183
+1699 1700
+1701 1700
+1701 1699
+1687 1702
+1687 1703
+1703 1702
+1704 1705
+1704 326
+326 1705
+1706 1707
+1363 1707
+1363 1706
+192 347
+192 930
+347 930
+1708 1709
+1708 1710
+1709 1710
+1711 1712
+1711 1713
+1713 1712
+1714 661
+1715 661
+1715 1714
+1716 1717
+1718 1717
+1718 1716
+191 1719
+191 1470
+1719 1470
+1720 1721
+1720 1722
+1722 1721
+1723 1724
+1723 1725
+1724 1725
+224 1726
+1726 222
+1727 1728
+1727 1729
+1729 1728
+1730 1731
+1732 1731
+1732 1730
+1034 407
+407 1036
+1733 1734
+1735 1734
+1735 1733
+1736 1737
+1738 1737
+1738 1736
+928 1030
+927 1030
+1739 1740
+1015 1739
+1015 1740
+1741 1742
+1741 1474
+1742 1474
+87 1743
+1743 86
+1744 456
+1745 456
+1745 1744
+659 1746
+1747 659
+1747 1746
+1630 1748
+1748 1065
+1749 1750
+1749 1751
+1751 1750
+1752 1753
+1752 1754
+1753 1754
+1755 1756
+1755 1757
+1757 1756
+1758 1759
+1572 1759
+1572 1758
+997 89
+1760 1761
+1760 1762
+1762 1761
+1763 607
+1763 251
+1764 1765
+942 1765
+942 1764
+1405 1766
+1767 1405
+1767 1766
+1768 1769
+1768 1770
+1769 1770
+1771 502
+1700 1771
+1700 502
+1772 1773
+1774 1772
+1774 1773
+536 1103
+534 1103
+1775 1053
+1775 1776
+1053 1776
+1019 1777
+1021 1777
+1778 236
+1778 1779
+1779 236
+1780 1781
+1782 1780
+1782 1781
+1783 1784
+660 1784
+660 1783
+1785 1485
+1785 641
+1786 1787
+1788 1786
+1788 1787
+1587 1789
+1587 1790
+1789 1790
+1791 1361
+1792 1361
+1792 1791
+1555 1793
+1794 1793
+1794 1555
+1334 1795
+1796 1334
+1796 1795
+727 1238
+727 1797
+1238 1797
+40 1798
+662 40
+662 1798
+1799 1800
+1801 1799
+1801 1800
+1737 1802
+1737 1803
+1802 1803
+487 1804
+1805 1804
+1805 487
+901 1806
+901 1807
+1806 1807
+1808 1809
+1810 1808
+1810 1809
+1811 1164
+1166 1811
+1210 1812
+1210 1813
+1812 1813
+1814 1815
+1816 1814
+1816 1815
+1817 1818
+1819 1818
+1819 1817
+1820 1821
+1822 1820
+1822 1821
+1823 1824
+1825 1823
+1825 1824
+1062 1826
+1827 1062
+1827 1826
+1828 1829
+1828 1830
+1830 1829
+1831 1832
+1831 1833
+1833 1832
+1403 397
+1834 397
+1834 1403
+917 406
+1835 917
+1835 406
+1836 1837
+1836 1832
+1837 1832
+1056 1838
+1055 1838
+1839 1840
+1841 1839
+1841 1840
+562 1842
+1843 1842
+1843 562
+1844 1845
+1844 1846
+1845 1846
+1315 1847
+1316 1847
+1848 1849
+1850 1848
+1850 1849
+608 1851
+1852 608
+1852 1851
+1853 1854
+1855 1854
+1855 1853
+1856 9
+1856 1513
+9 1513
+1857 1858
+1857 1859
+1858 1859
+1860 1861
+1862 1861
+1862 1860
+1863 1864
+1865 1863
+1865 1864
+1866 1313
+1866 1867
+1867 1313
+1868 1869
+1868 1870
+1869 1870
+1369 1871
+1872 1871
+1872 1369
+1873 1594
+1874 1594
+1874 1873
+1875 1876
+1875 1877
+1877 1876
+1878 1879
+1880 1879
+1880 1878
+1881 1537
+1882 1881
+1882 1537
+1883 1884
+1883 1439
+1884 1439
+342 1885
+342 1886
+1886 1885
+1887 1888
+1887 781
+1888 781
+1889 1882
+1432 1882
+1432 1889
+1890 1891
+1892 1890
+1892 1891
+1893 1894
+1893 1063
+1894 1063
+1895 1896
+1897 1896
+1897 1895
+1898 1878
+1898 1899
+1878 1899
+707 1900
+705 1900
+1901 1902
+1903 1902
+1903 1901
+1322 315
+1322 313
+439 1904
+1905 1904
+1905 439
+1906 1108
+1110 1906
+232 835
+1907 835
+1907 232
+1908 1909
+1638 1908
+1638 1909
+1910 1911
+1912 1910
+1912 1911
+1102 1913
+1914 1913
+1914 1102
+1915 1916
+1915 1917
+1917 1916
+1918 1919
+1920 1919
+1920 1918
+727 1921
+1238 1921
+1922 1923
+1924 1922
+1924 1923
+1925 899
+1925 1801
+1801 899
+1926 207
+1927 207
+1927 1926
+1189 1611
+1928 1929
+1928 1930
+1930 1929
+1931 1884
+1931 667
+667 1884
+103 1479
+1932 223
+222 1932
+121 1933
+1934 121
+1934 1933
+1935 1194
+1935 951
+1936 1532
+531 1936
+1215 1400
+1215 1937
+1937 1400
+1938 1939
+638 1938
+638 1939
+1940 1390
+66 1940
+1002 1941
+923 1002
+923 1941
+1942 1943
+1944 1942
+1944 1943
+1945 1946
+1945 1947
+1947 1946
+949 1948
+947 1948
+1949 1950
+1951 1950
+1951 1949
+4 1952
+808 1952
+1228 1252
+1228 1250
+1953 1954
+1955 1954
+1955 1953
+1956 1957
+1956 1696
+1696 1957
+1956 1958
+1958 1957
+1 1959
+1960 1959
+1960 1
+1110 356
+356 1109
+1961 1962
+1961 1963
+1963 1962
+1964 1965
+1414 1965
+1414 1964
+779 1966
+1967 1966
+1967 779
+1968 1969
+1970 1968
+1970 1969
+1723 1971
+1972 1971
+1972 1723
+1502 1785
+1502 927
+927 1785
+1973 1974
+1975 1974
+1975 1973
+1976 1977
+1978 1977
+1978 1976
+1979 1852
+1980 1852
+1980 1979
+1981 1982
+1981 1874
+1982 1874
+1983 1984
+1983 787
+787 1984
+1985 1986
+1987 1985
+1987 1986
+760 1914
+758 1914
+1988 1989
+1988 1990
+1990 1989
+1991 1992
+1991 1993
+1992 1993
+1994 1367
+454 1994
+532 1302
+985 1995
+490 1995
+490 985
+1996 1997
+1998 1997
+1998 1996
+1999 2000
+1999 2001
+2001 2000
+2002 172
+2003 2002
+2003 172
+2004 2005
+16 2004
+16 2005
+1339 1023
+2006 1023
+2006 1339
+2007 950
+2007 1974
+1974 950
+2008 2009
+2008 1622
+1622 2009
+2010 2011
+1970 2010
+1970 2011
+2012 2013
+1827 2012
+1827 2013
+1219 1815
+1061 1815
+198 553
+198 274
+274 553
+2014 1688
+2014 1690
+2015 2016
+2015 2017
+2017 2016
+2018 2019
+92 2018
+92 2019
+166 1228
+166 290
+2020 1806
+901 2020
+2021 2022
+2021 1282
+1282 2022
+2023 2024
+2023 2025
+2025 2024
+2026 2027
+2028 2027
+2028 2026
+2029 845
+2029 1489
+1489 845
+393 2030
+2031 2030
+2031 393
+147 2032
+2033 2032
+2033 147
+1680 2034
+1678 2034
+2035 2036
+2035 2037
+2036 2037
+929 2038
+931 2038
+284 2039
+2040 2039
+2040 284
+2041 2042
+2041 2043
+2043 2042
+2044 1575
+2044 373
+1575 373
+2045 2046
+2047 2045
+2047 2046
+605 570
+603 570
+291 2048
+289 2048
+2049 859
+2049 858
+1602 1840
+1602 2050
+2050 1840
+558 100
+2051 100
+2051 558
+2052 373
+2044 2052
+2053 2054
+2053 1010
+2054 1010
+2055 1294
+2056 1294
+2056 2055
+2057 2058
+2057 2059
+2058 2059
+2060 2061
+2062 2060
+2062 2061
+2063 2064
+2063 2065
+2064 2065
+2066 2067
+2066 291
+2067 291
+2068 2069
+2070 2069
+2070 2068
+2071 2072
+2071 2073
+2073 2072
+1778 2074
+1778 1631
+2074 1631
+265 2075
+265 2076
+2076 2075
+2077 2078
+2079 2078
+2079 2077
+2080 2081
+2082 2080
+2082 2081
+2083 2084
+988 2083
+988 2084
+2085 1534
+2085 2086
+2086 1534
+2087 2088
+2087 2089
+2089 2088
+2090 2091
+2090 2092
+2091 2092
+182 2093
+1218 2093
+1218 182
+2094 1886
+2095 2094
+2095 1886
+2096 2097
+2096 1271
+2097 1271
+2098 2099
+2098 2100
+2099 2100
+2101 2102
+2101 2103
+2102 2103
+2104 2105
+2104 2106
+2106 2105
+913 2107
+2108 913
+2108 2107
+2109 2110
+2109 2111
+2111 2110
+2112 2113
+2112 2114
+2114 2113
+2064 358
+2064 357
+2115 207
+2116 207
+2116 2115
+1710 2117
+1708 2117
+2118 699
+2119 699
+2119 2118
+2120 462
+2121 462
+2121 2120
+2122 2123
+2124 2123
+2124 2122
+1335 2125
+2126 2125
+2126 1335
+1147 2127
+1148 2127
+2128 2129
+2130 2129
+2130 2128
+1069 2131
+1178 1069
+1178 2131
+2132 2133
+1601 2133
+1601 2132
+887 2134
+887 2135
+2134 2135
+2136 837
+2137 837
+2137 2136
+2138 2139
+2140 2138
+2140 2139
+1665 2141
+2141 35
+2142 2143
+2144 2143
+2144 2142
+2145 2146
+2147 2146
+2147 2145
+2148 2149
+2150 2149
+2150 2148
+2095 1563
+2151 2095
+2151 1563
+203 2152
+2153 2152
+2153 203
+2154 2155
+1368 2155
+1368 2154
+2156 2157
+2158 2157
+2158 2156
+2159 2160
+2161 2159
+2161 2160
+2162 2163
+2164 2162
+2164 2163
+2165 2166
+2165 2167
+2167 2166
+2168 2169
+2170 2169
+2170 2168
+6 2171
+6 1274
+1274 2171
+1698 1182
+2172 1698
+2172 1182
+2173 196
+256 196
+256 2173
+2174 2175
+2174 2176
+2175 2176
+555 514
+1188 1215
+1188 2177
+1215 2177
+1694 2178
+2179 2178
+2179 1694
+116 2180
+2181 2180
+2181 116
+78 2182
+77 2182
+2183 2184
+1999 2184
+1999 2183
+2162 2025
+2162 2024
+846 2064
+2063 846
+2185 2186
+2187 2186
+2187 2185
+2188 1776
+1775 2188
+683 2189
+683 2190
+2189 2190
+2191 1948
+949 2191
+2192 2193
+2194 2192
+2194 2193
+1317 642
+640 1317
+2195 2196
+1489 2196
+1489 2195
+2197 426
+425 2197
+2032 2198
+2199 2032
+2199 2198
+2200 2201
+2202 2201
+2202 2200
+2203 2204
+1683 2203
+1683 2204
+2205 2206
+2205 2207
+2207 2206
+1436 2208
+1435 2208
+2209 626
+732 2209
+732 626
+873 526
+2210 1545
+2210 1547
+2211 1736
+2211 2212
+1736 2212
+2213 470
+468 2213
+2214 2215
+2216 2215
+2216 2214
+2217 2218
+2217 1901
+1901 2218
+1094 2219
+1093 2219
+2220 2221
+2222 2221
+2222 2220
+1092 2223
+1092 2168
+2168 2223
+2224 473
+2224 2225
+473 2225
+2226 2227
+2228 2227
+2228 2226
+1057 2229
+106 2229
+2230 2231
+1169 2231
+1169 2230
+2232 293
+294 2232
+2233 1249
+2234 1249
+2234 2233
+2235 2236
+2235 262
+262 2236
+2237 2238
+1839 2238
+1839 2237
+2015 2239
+2015 478
+478 2239
+2240 616
+2241 616
+2241 2240
+2242 2243
+828 2243
+828 2242
+2244 2245
+2244 2246
+2246 2245
+2247 282
+2248 282
+2248 2247
+1761 2249
+2250 1761
+2250 2249
+1588 2006
+1588 1339
+2251 1959
+1960 2251
+2252 1833
+2252 1832
+1730 895
+894 1730
+2253 2254
+1488 2253
+1488 2254
+2006 1590
+2255 1976
+2255 1977
+2256 2257
+2258 2257
+2258 2256
+2118 935
+2119 935
+380 2259
+2260 2259
+2260 380
+2261 2262
+2263 2262
+2263 2261
+2264 1310
+2264 1309
+2265 2266
+2267 2266
+2267 2265
+249 2268
+249 2269
+2268 2269
+1438 361
+359 1438
+2270 2204
+2271 2204
+2271 2270
+2120 2272
+2273 2272
+2273 2120
+2274 1245
+1448 2274
+89 2275
+2276 89
+2276 2275
+2277 2278
+2277 2279
+2279 2278
+2280 2160
+2280 2281
+2160 2281
+2211 2282
+2211 2283
+2282 2283
+2284 2285
+2286 2285
+2286 2284
+2220 250
+2220 606
+250 606
+2287 1447
+1982 2287
+1982 1447
+2288 659
+2288 1747
+583 2289
+582 2289
+1105 499
+1105 7
+7 499
+2290 2291
+2292 2290
+2292 2291
+2293 2294
+2295 2293
+2295 2294
+1291 1570
+1291 1387
+1387 1570
+2296 956
+2297 2296
+2297 956
+2298 2299
+1771 2298
+1771 2299
+2300 1679
+2301 2300
+2301 1679
+2302 572
+2302 571
+2303 1612
+2303 1611
+672 1133
+1380 672
+2304 2305
+2304 2306
+2306 2305
+1834 2307
+2307 1403
+2308 2309
+2308 2310
+2309 2310
+1900 2311
+707 2311
+2312 2313
+2312 2314
+2313 2314
+79 1976
+79 2315
+1976 2315
+836 2316
+836 746
+2316 746
+2317 2318
+2319 2317
+2319 2318
+1170 2320
+2321 1170
+2321 2320
+2319 2322
+2322 2317
+2323 2324
+2323 2325
+2325 2324
+2326 2041
+2327 2326
+2327 2041
+2328 2329
+2330 2328
+2330 2329
+2331 2332
+2333 2332
+2333 2331
+1791 1359
+2334 1791
+2334 1359
+2335 312
+2335 67
+67 312
+2336 139
+2336 560
+2337 2338
+2339 2337
+2339 2338
+2340 2341
+2342 2340
+2342 2341
+1274 2343
+1274 2344
+2343 2344
+1060 2345
+453 2345
+453 1060
+2346 1058
+2335 1058
+2335 2346
+743 2347
+2348 743
+2348 2347
+2349 2350
+2351 2349
+2351 2350
+2352 2353
+2354 2353
+2354 2352
+2355 569
+2355 568
+712 2356
+711 2356
+2357 2358
+2357 269
+2358 269
+1538 2359
+2360 1538
+2360 2359
+2361 2362
+1858 2362
+1858 2361
+756 2363
+1223 2363
+2364 349
+350 2364
+2365 2366
+1254 2365
+1254 2366
+2367 2368
+2369 2367
+2369 2368
+2370 2371
+2370 2372
+2371 2372
+2373 2374
+2373 505
+505 2374
+1422 2375
+1509 2375
+2376 2377
+2378 2377
+2378 2376
+2379 2380
+2381 2380
+2381 2379
+2382 2383
+2382 2384
+2383 2384
+2385 2386
+1119 2386
+1119 2385
+1103 1913
+1753 2387
+1752 2387
+1656 2388
+2389 2388
+2389 1656
+2390 1505
+2391 1505
+2391 2390
+2392 1384
+2392 298
+2393 2394
+2393 2395
+2394 2395
+1698 2396
+2172 2396
+792 2397
+2398 792
+2398 2397
+2399 2400
+2401 2400
+2401 2399
+2402 2403
+2402 2404
+2404 2403
+2405 2406
+2407 2406
+2407 2405
+1438 1884
+1513 8
+2408 1513
+2408 8
+2029 2195
+2409 1930
+2409 2410
+1930 2410
+1393 2411
+1393 2412
+2411 2412
+2413 510
+2413 512
+2028 2414
+2027 2414
+2415 2416
+1427 2416
+1427 2415
+2417 2418
+2419 2417
+2419 2418
+614 692
+2420 614
+2420 692
+286 2421
+284 2421
+53 2422
+2423 53
+2423 2422
+2424 881
+1633 2424
+2425 1848
+2425 2426
+1848 2426
+798 2427
+796 2427
+331 2428
+333 2428
+1311 2256
+1311 2302
+2256 2302
+1328 2429
+277 2429
+277 1328
+2430 222
+2430 1726
+2431 2432
+2433 2431
+2433 2432
+2434 2435
+1273 2435
+1273 2434
+2436 2437
+2438 2436
+2438 2437
+584 153
+1379 153
+678 2439
+2440 678
+2440 2439
+2441 703
+2441 2442
+703 2442
+1374 1330
+1374 1329
+2443 2444
+2445 2444
+2445 2443
+1479 520
+1479 522
+178 2072
+178 2446
+2072 2446
+2447 2448
+2447 593
+593 2448
+2208 2449
+1436 2449
+1662 2450
+2451 2450
+2451 1662
+2452 2453
+2452 2454
+2453 2454
+2455 2456
+2457 2456
+2457 2455
+2458 2459
+2460 2458
+2460 2459
+2461 195
+2462 195
+2462 2461
+910 2463
+2464 2463
+2464 910
+2465 1612
+2303 2465
+2466 2467
+2466 1997
+2467 1997
+1655 2468
+1655 2469
+2469 2468
+2470 2471
+370 2471
+370 2470
+1745 1949
+1744 1949
+2472 2473
+2472 2474
+2474 2473
+2475 2476
+2475 810
+2476 810
+2477 2478
+209 2478
+209 2477
+2479 2480
+2479 1688
+2480 1688
+2481 2482
+2483 2482
+2483 2481
+2484 2485
+2484 2486
+2486 2485
+2487 2068
+2119 2487
+2119 2068
+263 1256
+2488 1256
+2488 263
+2252 2425
+1833 2425
+2489 2490
+2489 2491
+2490 2491
+1510 1859
+2492 1510
+2492 1859
+2493 2494
+19 2494
+19 2493
+2495 2496
+2497 2496
+2497 2495
+585 2498
+2499 2498
+2499 585
+2500 2501
+1482 2500
+1482 2501
+2312 2502
+2312 2206
+2206 2502
+544 822
+822 545
+2503 742
+2503 2504
+2504 742
+1557 2505
+1557 2500
+2500 2505
+2506 1608
+593 1608
+593 2506
+2507 1929
+2507 1928
+744 738
+744 740
+2508 2509
+2510 2509
+2510 2508
+625 2511
+624 2511
+2512 236
+2513 2512
+2513 236
+2514 199
+60 199
+60 2514
+2515 63
+62 2515
+1106 7
+1106 9
+131 2516
+386 2516
+2517 1864
+2517 1863
+2518 1986
+2519 2518
+2519 1986
+713 2520
+712 2520
+397 2521
+1834 2521
+2522 2523
+2522 2524
+2524 2523
+2525 354
+2526 354
+2526 2525
+2527 2528
+2529 2528
+2529 2527
+162 2530
+1410 2530
+1410 162
+1714 660
+2531 2532
+2533 2532
+2533 2531
+2534 1622
+2008 2534
+2057 948
+947 2057
+690 459
+690 458
+2535 2191
+2535 949
+2536 2537
+2536 1337
+2537 1337
+2538 2539
+2540 2538
+2540 2539
+278 2541
+2541 279
+2542 2543
+2544 2542
+2544 2543
+2545 985
+2545 983
+1881 2546
+1881 2547
+2546 2547
+2548 2549
+2548 2550
+2549 2550
+2551 1096
+1095 2551
+2552 2553
+2552 2554
+2553 2554
+364 748
+2555 2556
+2555 2557
+2556 2557
+2096 2558
+1273 2558
+1273 2096
+2559 2560
+2561 2560
+2561 2559
+2106 679
+2562 679
+2562 2106
+1199 2563
+2563 1200
+2564 2058
+2564 2057
+620 1700
+2565 620
+2565 1700
+1683 770
+2566 770
+2566 1683
+2374 506
+825 1543
+823 1543
+2567 2568
+2569 2568
+2569 2567
+2570 1532
+2571 1532
+2571 2570
+2150 486
+2149 486
+2572 573
+572 2572
+2573 2574
+2575 2574
+2575 2573
+2576 530
+1022 2576
+2577 731
+730 2577
+2578 2160
+2579 2578
+2579 2160
+709 2580
+2544 2580
+2544 709
+2581 2582
+2581 2583
+2583 2582
+2091 1790
+2091 1789
+2584 1808
+2585 1808
+2585 2584
+1176 1070
+1178 1070
+2586 2587
+2588 2586
+2588 2587
+2589 1924
+2590 1924
+2590 2589
+1937 2440
+2591 2440
+2591 1937
+2592 704
+2593 704
+2593 2592
+2594 2595
+475 2595
+475 2594
+2596 2597
+2598 2596
+2598 2597
+2599 2600
+2599 2601
+2600 2601
+2602 1695
+2602 1697
+2603 2604
+2605 2604
+2605 2603
+671 2606
+2606 670
+1569 2607
+1567 2607
+2608 2609
+2608 2610
+2610 2609
+2611 2612
+2613 2612
+2613 2611
+1022 2614
+529 2614
+2615 2616
+2615 2617
+2616 2617
+2618 2619
+2620 2619
+2620 2618
+1047 2621
+2621 1046
+2622 2312
+2622 2314
+961 1909
+961 1908
+1128 1201
+1129 1201
+2623 2024
+2624 2623
+2624 2024
+2090 2625
+2090 2626
+2625 2626
+2627 2628
+2627 2629
+2628 2629
+2630 1082
+2631 1082
+2631 2630
+409 2296
+2632 409
+2632 2296
+1777 2633
+1021 2633
+1417 1452
+2634 1452
+2634 1417
+2635 2539
+786 2635
+786 2539
+2636 2637
+2636 2397
+2637 2397
+1646 1974
+1973 1646
+1568 2638
+2639 2638
+2639 1568
+2640 2597
+2598 2640
+2641 2206
+2205 2641
+550 1353
+550 1324
+2533 2642
+2533 2643
+2642 2643
+2644 1766
+2645 2644
+2645 1766
+1276 897
+2646 897
+2646 1276
+432 2647
+432 2648
+2648 2647
+44 1627
+2649 1627
+2649 44
+2135 2650
+1681 2135
+1681 2650
+1899 1754
+1898 1754
+2651 2652
+2651 2653
+2652 2653
+2654 2238
+2654 1839
+2655 885
+1100 2655
+1100 885
+1773 2656
+1772 2656
+2657 2367
+2657 2658
+2367 2658
+2659 1286
+496 2659
+496 1286
+2660 2661
+2662 2661
+2662 2660
+2540 1747
+2538 1747
+2663 1463
+2664 1463
+2664 2663
+2204 2665
+2204 1684
+2665 1684
+2666 2667
+2666 2668
+2667 2668
+2669 127
+2669 128
+2670 2644
+2671 2670
+2671 2644
+83 2672
+82 2672
+698 549
+2673 698
+2673 549
+2674 2675
+1029 2675
+1029 2674
+2676 2677
+2676 279
+279 2677
+2678 2679
+2680 2678
+2680 2679
+2681 2682
+2683 2681
+2683 2682
+2684 2685
+1918 2684
+1918 2685
+2686 438
+2686 2687
+2687 438
+1602 1841
+834 2688
+2688 832
+2689 519
+2689 2690
+519 2690
+2107 2326
+1757 2326
+1757 2107
+2491 560
+2491 140
+2691 2169
+2692 2169
+2692 2691
+360 2693
+2694 2693
+2694 360
+2279 2695
+2301 2279
+2301 2695
+4 2696
+2697 2696
+2697 4
+1279 2698
+2699 1279
+2699 2698
+2486 2700
+2701 2700
+2701 2486
+2702 1692
+2703 2702
+2703 1692
+2704 2025
+2023 2704
+224 2705
+1726 2705
+919 484
+919 54
+78 117
+78 115
+1977 2706
+2255 2706
+2591 1400
+472 1454
+472 2707
+1454 2707
+417 2704
+2704 770
+99 1213
+98 1213
+2549 2708
+2709 2708
+2709 2549
+2710 1497
+393 2710
+393 1497
+2333 2711
+2711 2331
+2439 2712
+2713 2439
+2713 2712
+2550 1115
+1116 2550
+2714 2715
+2714 2716
+2715 2716
+2717 2306
+2717 837
+2306 837
+2718 1911
+2719 1911
+2719 2718
+2720 2721
+2720 1037
+1037 2721
+1552 2722
+1552 1915
+2722 1915
+2723 2188
+2724 2188
+2724 2723
+2725 2726
+2727 2726
+2727 2725
+743 2728
+2729 743
+2729 2728
+2730 2731
+596 2730
+596 2731
+2202 2052
+2052 2200
+2732 2607
+1567 2732
+75 191
+73 191
+2733 2734
+2733 2735
+2735 2734
+2736 2601
+2737 2736
+2737 2601
+1456 838
+1617 838
+1617 1456
+2738 1246
+958 1246
+958 2738
+1925 2739
+1925 1647
+2739 1647
+2292 2303
+2292 1611
+1666 36
+146 1468
+2032 1468
+2032 146
+2740 34
+1755 2740
+1755 34
+2674 2741
+2674 1030
+2741 1030
+1704 2742
+1704 2743
+2743 2742
+24 363
+362 24
+307 1594
+307 2744
+1594 2744
+2526 2745
+2526 355
+2745 355
+2683 903
+2683 902
+1991 2746
+1991 2747
+2746 2747
+1135 2748
+1133 2748
+2749 2214
+2749 2215
+2482 39
+2482 38
+2750 1919
+171 1919
+171 2750
+2697 2751
+2696 2751
+2752 481
+2753 2752
+2753 481
+2524 808
+613 808
+613 2524
+2754 866
+2754 865
+1680 2279
+1680 2301
+636 2755
+636 2339
+2339 2755
+389 1551
+2756 2757
+2756 2758
+2757 2758
+1212 242
+2759 1790
+2760 1790
+2760 2759
+173 413
+173 2761
+2761 413
+2133 2762
+2763 2762
+2763 2133
+2764 2765
+2766 2765
+2766 2764
+2161 2767
+2768 2161
+2768 2767
+1690 2769
+1689 2769
+2770 2718
+2770 2771
+2771 2718
+705 2772
+705 129
+129 2772
+2773 2774
+2775 2773
+2775 2774
+926 641
+640 926
+1811 2776
+2777 1811
+2777 2776
+2778 760
+2778 759
+624 61
+624 2779
+61 2779
+2780 2781
+2782 2780
+2782 2781
+2783 65
+2783 64
+2784 773
+2664 773
+2664 2784
+2161 2578
+2785 982
+2785 1137
+654 2786
+495 654
+495 2786
+2787 2788
+2789 2788
+2789 2787
+230 2790
+230 2791
+2791 2790
+2792 2793
+2792 2794
+2794 2793
+81 2795
+79 2795
+2796 870
+2797 2796
+2797 870
+2401 2798
+2799 2798
+2799 2401
+2192 2800
+2192 2801
+2801 2800
+491 278
+492 278
+2802 1929
+2803 1929
+2803 2802
+2804 2805
+2806 2805
+2806 2804
+2807 2196
+2195 2807
+2657 628
+2808 628
+2808 2657
+135 2809
+135 2810
+2810 2809
+2811 21
+2811 20
+2812 2813
+1889 2813
+1889 2812
+2811 508
+2811 541
+2814 2815
+2816 2815
+2816 2814
+2817 306
+2817 1341
+1341 306
+1870 2685
+1920 2685
+1920 1870
+1356 1695
+2602 1356
+2591 2818
+2818 2440
+1362 2819
+1362 2820
+2820 2819
+1780 1332
+2821 1332
+2821 1780
+1805 486
+2822 845
+163 2822
+2823 2824
+639 2824
+639 2823
+244 2825
+244 1296
+1296 2825
+2742 326
+963 1909
+2826 1909
+2826 963
+2827 2828
+2829 2827
+2829 2828
+2613 2002
+2613 2830
+2002 2830
+1629 44
+2732 44
+2732 1629
+2831 1823
+2831 2832
+1823 2832
+2833 1271
+2097 2833
+1525 2057
+2564 1525
+2834 2835
+2316 2835
+2316 2834
+2836 390
+2837 2836
+2837 390
+2838 2621
+2839 2621
+2839 2838
+2840 1288
+2840 2443
+1288 2443
+240 2841
+238 2841
+2842 2843
+2844 2843
+2844 2842
+1370 1490
+1370 1570
+1490 1570
+2682 2845
+2682 2846
+2846 2845
+295 47
+736 295
+920 2372
+592 2372
+2469 2069
+2468 2069
+2847 2209
+2847 732
+1236 1364
+1804 1236
+1804 1364
+30 2848
+28 2848
+1745 455
+1489 1386
+2822 1386
+2822 1489
+839 1457
+1457 838
+2849 1028
+2850 2849
+2850 1028
+2851 2852
+2851 337
+2852 337
+32 2853
+763 32
+763 2853
+875 1143
+875 366
+1143 366
+2854 1916
+1915 2854
+2855 905
+1154 2855
+2856 837
+2856 2137
+1100 2857
+1099 2857
+1343 2456
+2221 2456
+2221 1343
+2097 2858
+2859 2858
+2859 2097
+1578 2860
+1578 2861
+2860 2861
+2862 2863
+2862 1637
+1637 2863
+2689 214
+2689 1175
+1175 214
+2487 2864
+934 2864
+934 2487
+2865 2831
+2866 2831
+2866 2865
+2596 2867
+2868 2596
+2868 2867
+2143 2869
+2144 2869
+2386 2870
+2681 2386
+2681 2870
+2863 193
+2871 193
+2871 2863
+2872 2873
+130 2872
+130 2873
+964 2874
+964 2370
+2370 2874
+1995 984
+40 661
+42 661
+2875 2876
+1657 2875
+1657 2876
+899 1807
+1801 1807
+2877 2878
+2877 138
+138 2878
+1194 1673
+1194 2879
+1673 2879
+2880 2881
+2882 2881
+2882 2880
+2883 595
+2883 1388
+2884 2819
+1362 2884
+2885 2240
+2885 616
+2886 1722
+2887 1722
+2887 2886
+2888 139
+2336 2888
+2889 1653
+2890 1653
+2890 2889
+1735 2891
+1735 2892
+2891 2892
+1228 2893
+1228 2788
+2788 2893
+1788 674
+1788 673
+1026 2894
+1481 2894
+2895 2896
+2895 2897
+2896 2897
+2692 2168
+2898 2899
+2900 2899
+2900 2898
+2481 2901
+2481 1600
+1600 2901
+2808 2902
+2808 2903
+2902 2903
+2904 2905
+2904 1001
+1001 2905
+508 2906
+540 2906
+639 2907
+2823 2907
+2146 797
+2145 797
+2831 346
+2865 346
+2908 2873
+2908 2872
+2909 2910
+2862 2909
+2862 2910
+2548 896
+894 2548
+2911 1042
+2911 1041
+2417 2912
+2418 2912
+2913 993
+2913 2914
+993 2914
+854 1793
+854 2915
+1793 2915
+2916 663
+2917 2916
+2917 663
+851 2918
+851 2919
+2919 2918
+2025 770
+2920 1926
+2920 2477
+2477 1926
+304 1787
+305 1787
+2921 2922
+2921 2923
+2923 2922
+2924 194
+2871 2924
+2871 194
+2690 2925
+2690 733
+2925 733
+2926 2927
+2926 2928
+2927 2928
+1432 1711
+1432 1713
+2929 2930
+2929 2931
+2930 2931
+2932 2933
+1219 2933
+1219 2932
+2750 1193
+2750 2934
+2934 1193
+519 2925
+113 2935
+2936 113
+2936 2935
+2937 2938
+2939 2937
+2939 2938
+2940 2941
+2942 2941
+2942 2940
+2943 2944
+2782 2943
+2782 2944
+2945 2946
+2947 2946
+2947 2945
+2094 672
+2094 342
+342 672
+2948 1323
+443 2948
+443 1323
+1931 1438
+359 1931
+2398 2637
+2949 2950
+2949 2951
+2951 2950
+2952 2632
+1751 2632
+1751 2952
+1011 743
+1011 2348
+2953 1257
+2953 1409
+1475 2547
+1881 1475
+2954 2955
+2956 2955
+2956 2954
+2957 773
+2957 2958
+773 2958
+2959 2960
+2249 2960
+2249 2959
+2961 1986
+2961 1985
+1479 521
+1704 2962
+1704 1378
+2962 1378
+1404 1326
+1556 2963
+2964 1556
+2964 2963
+2965 2195
+2965 2807
+474 2966
+2138 474
+2138 2966
+2967 2968
+2969 2968
+2969 2967
+725 2970
+725 2971
+2971 2970
+1937 1214
+2713 1214
+2713 1937
+435 2972
+2973 2972
+2973 435
+2974 2975
+2877 2975
+2877 2974
+2758 2976
+988 2976
+988 2758
+907 762
+907 763
+2666 2812
+2812 2668
+1859 2977
+2978 2977
+2978 1859
+2979 1618
+2980 1618
+2980 2979
+807 2981
+1445 2981
+1445 807
+534 1913
+1978 2982
+2983 2982
+2983 1978
+2620 2984
+2620 2985
+2985 2984
+2661 1558
+2986 2661
+2986 1558
+2987 2988
+1051 2988
+1051 2987
+34 2141
+2989 1336
+2989 1334
+1396 679
+1395 679
+2990 2515
+2991 2990
+2991 2515
+138 2992
+2992 2878
+2993 2994
+2993 1218
+1218 2994
+1081 2995
+1081 2996
+2995 2996
+2127 1660
+2997 2127
+2997 1660
+2942 1337
+2536 2942
+2928 1804
+2928 2998
+2998 1804
+2999 1496
+2999 1495
+3000 3001
+3002 3001
+3002 3000
+1716 179
+3003 179
+3003 1716
+827 2242
+827 3004
+3004 2242
+2472 1269
+1268 2472
+299 3005
+299 3006
+3006 3005
+3007 3008
+3009 3008
+3009 3007
+17 863
+17 864
+3010 854
+3010 2915
+2856 1896
+2856 3011
+1896 3011
+3012 3013
+3014 3013
+3014 3012
+3015 928
+3015 926
+2228 1141
+1141 2227
+1842 3016
+1830 3016
+1830 1842
+2050 3017
+2050 3018
+3018 3017
+3019 3020
+3019 3021
+3021 3020
+1187 3022
+3022 1185
+3007 1264
+1264 3008
+3023 1731
+3024 1731
+3024 3023
+3025 1339
+3025 1023
+542 531
+542 1936
+819 3026
+420 3026
+420 819
+3027 3028
+3027 2455
+2455 3028
+3029 3030
+3031 3029
+3031 3030
+1346 3032
+11 3032
+11 1346
+3033 306
+2817 3033
+2286 3034
+1524 2286
+1524 3034
+2967 374
+2968 374
+3035 644
+3035 643
+3036 829
+3036 2798
+829 2798
+3037 3038
+3039 3038
+3039 3037
+491 3040
+491 280
+280 3040
+3041 3042
+3043 3042
+3043 3041
+3044 3045
+3044 2648
+2648 3045
+1123 2604
+3046 1123
+3046 2604
+2652 2454
+2652 3047
+3047 2454
+2216 3048
+2216 3049
+3048 3049
+200 3050
+200 2514
+2514 3050
+3051 952
+3051 1194
+2085 2525
+2085 3052
+2525 3052
+3053 2314
+2622 3053
+3054 3055
+1630 3054
+1630 3055
+3056 983
+3056 984
+1192 134
+1192 734
+134 734
+2233 1063
+266 2233
+266 1063
+694 609
+696 609
+1034 917
+1034 916
+3057 3058
+3057 225
+3058 225
+3059 3060
+2581 3060
+2581 3059
+12 3061
+11 3061
+2566 769
+3062 1236
+1235 3062
+3063 3064
+3063 3065
+3065 3064
+1912 3066
+1910 3066
+3067 3068
+3069 3068
+3069 3067
+3070 3062
+3071 3062
+3071 3070
+42 3072
+3072 41
+3073 277
+3073 276
+2794 412
+3074 412
+3074 2794
+3075 3076
+3075 3077
+3076 3077
+3078 3079
+1619 3079
+1619 3078
+1618 2717
+2304 2717
+2304 1618
+2566 3080
+1683 3080
+3081 3082
+3081 2901
+3082 2901
+2631 2866
+2866 2630
+591 2284
+979 2284
+2052 3083
+2202 3083
+2170 2223
+614 691
+3084 3085
+3084 1360
+3085 1360
+3086 3087
+3086 1504
+1504 3087
+1177 1364
+3088 3089
+3090 3089
+3090 3088
+1800 3091
+1800 3092
+3092 3091
+1603 3093
+2035 3093
+2035 1603
+2264 3094
+2264 3095
+3095 3094
+166 1252
+1077 3096
+2170 1077
+2170 3096
+3097 3098
+430 3098
+430 3097
+3099 1948
+947 3099
+3100 2061
+2060 3100
+3101 1779
+3102 3101
+3102 1779
+1267 3103
+1266 3103
+1423 2375
+289 2788
+3104 2337
+3105 2337
+3105 3104
+2659 1287
+3106 1287
+3106 2659
+1703 3107
+1687 3107
+151 911
+151 3108
+911 3108
+3109 2395
+3110 3109
+3110 2395
+340 3111
+341 3111
+3112 3113
+1186 3112
+1186 3113
+1691 2568
+2529 2568
+2529 1691
+3114 3115
+2445 3115
+2445 3114
+630 3116
+628 3116
+2706 3117
+2706 2975
+2975 3117
+3118 1075
+3119 1075
+3119 3118
+3120 3121
+3120 3122
+3122 3121
+3123 3124
+3125 3124
+3125 3123
+1143 877
+3126 1143
+3126 877
+3127 3128
+3129 3128
+3129 3127
+1669 3122
+1669 3121
+1246 3130
+2103 1246
+2103 3130
+2470 1966
+2471 1966
+1796 3131
+1796 3132
+3131 3132
+2841 1529
+3133 1331
+1529 1331
+1529 3133
+3134 3135
+2887 3135
+2887 3134
+3136 3137
+3136 2670
+2670 3137
+556 3138
+774 3138
+3139 516
+3140 516
+3140 3139
+2469 547
+2469 697
+547 697
+2307 3141
+1403 3141
+3142 2946
+3143 2946
+3143 3142
+1187 3144
+1187 3145
+3144 3145
+1050 1540
+1050 3117
+1540 3117
+1148 2827
+1146 2827
+3146 553
+3146 3147
+553 3147
+2134 3148
+3148 2135
+751 2563
+2563 325
+3093 3149
+1589 3093
+1589 3149
+1691 3150
+3150 1692
+3151 1663
+3152 1663
+3152 3151
+3153 682
+3153 248
+3154 3155
+3154 1563
+3155 1563
+449 3156
+449 3157
+3156 3157
+3158 3159
+3160 3158
+3160 3159
+1265 3161
+3161 1263
+3162 1666
+3162 1665
+2260 3163
+2260 3164
+3164 3163
+3165 3166
+94 3166
+94 3165
+3167 336
+3167 2675
+336 2675
+347 3168
+3168 930
+1167 3169
+1169 3169
+3170 3171
+3170 3172
+3172 3171
+3173 1554
+274 3173
+274 1554
+1727 1469
+1772 1727
+1772 1469
+2084 2976
+1234 3174
+1234 2141
+3174 2141
+503 1700
+461 2120
+2509 404
+2508 404
+3175 1063
+3175 2233
+2600 3176
+2177 2600
+2177 3176
+3177 3178
+3179 3178
+3179 3177
+3180 1077
+3180 3181
+3181 1077
+2360 3182
+2359 3182
+3183 3184
+3185 3183
+3185 3184
+3186 1506
+3186 1505
+3187 3188
+3101 3188
+3101 3187
+1957 3189
+1958 3189
+120 3190
+3190 119
+3191 3192
+504 3191
+504 3192
+3193 1314
+2422 3193
+2422 1314
+1850 3194
+3195 1850
+3195 3194
+3196 1612
+1580 3196
+2761 412
+2567 219
+219 2568
+138 3197
+2877 3197
+1686 3107
+2169 3198
+3199 2169
+3199 3198
+2478 208
+3200 2478
+3200 208
+2223 1077
+214 2690
+2079 3201
+2078 3201
+3202 2383
+3202 2382
+57 1612
+2465 57
+2156 1613
+2156 559
+3203 3204
+2934 3203
+2934 3204
+2102 1246
+3205 1943
+3205 1559
+1559 1943
+2697 612
+3206 2697
+3206 612
+3207 2946
+3207 62
+62 2946
+3208 1809
+3209 3208
+3209 1809
+2254 3013
+3012 2254
+3210 3211
+3210 1465
+3211 1465
+3212 3213
+3214 3213
+3214 3212
+3215 1269
+2472 3215
+255 3216
+2121 3216
+2121 255
+2383 2403
+2383 2402
+3217 3218
+3217 3219
+3219 3218
+3220 3221
+3220 3222
+3222 3221
+1110 1573
+1906 1573
+2810 3223
+135 3223
+3211 2892
+3224 3211
+3224 2892
+3225 2498
+3225 681
+681 2498
+3226 3227
+2854 3227
+2854 3226
+2096 3228
+696 3228
+696 2096
+3229 3230
+3229 3231
+3231 3230
+3232 3233
+3232 3234
+3234 3233
+3235 2852
+472 2852
+472 3235
+3236 676
+3236 677
+74 2029
+73 2029
+2275 2129
+997 2129
+997 2275
+3032 1347
+3237 679
+3237 680
+1434 2000
+3238 1434
+3238 2000
+1176 1235
+3239 1568
+1567 3239
+2081 1382
+2081 384
+668 3240
+3241 668
+3241 3240
+620 574
+618 574
+2803 1930
+3242 2043
+2041 3242
+3243 3244
+143 3244
+143 3243
+232 3245
+234 3245
+3246 877
+3247 3246
+3247 877
+686 3248
+918 686
+918 3248
+1270 2688
+1270 832
+1027 2850
+3249 3250
+3251 3249
+3251 3250
+3252 1343
+3253 3252
+3253 1343
+3254 2539
+3254 2538
+3255 1699
+3256 1699
+3256 3255
+3099 3257
+3257 1948
+1570 1369
+3258 963
+962 3258
+3259 2472
+3259 1268
+2126 1688
+3260 1688
+3260 2126
+3261 3262
+3261 3263
+3263 3262
+3264 3265
+3266 3264
+3266 3265
+3267 3268
+3269 3268
+3269 3267
+2663 1462
+3270 1381
+3270 1380
+2040 3271
+3272 3271
+3272 2040
+2895 2194
+2895 2193
+3273 3274
+3273 2473
+3274 2473
+3261 3275
+3261 3276
+3276 3275
+2322 3039
+2322 3037
+3277 3278
+3279 3277
+3279 3278
+3280 3281
+3282 3281
+3282 3280
+3283 2853
+3283 32
+3284 3285
+3284 2117
+3285 2117
+788 755
+754 788
+3286 1380
+3286 3287
+1380 3287
+170 2934
+2750 170
+422 3288
+3289 3288
+3289 422
+3290 1470
+3290 1472
+2971 984
+3056 2971
+3291 2762
+3291 2763
+2531 3292
+3293 3292
+3293 2531
+3294 3219
+1449 3219
+1449 3294
+3128 1031
+3295 3128
+3295 1031
+3296 3297
+3296 3298
+3298 3297
+375 3299
+3300 3299
+3300 375
+2415 860
+3301 2415
+3301 860
+1917 2106
+1917 3302
+2106 3302
+640 1319
+2475 3303
+2475 2424
+2424 3303
+3304 3305
+3306 3305
+3306 3304
+2583 3307
+3308 3307
+3308 2583
+1703 3309
+1702 3309
+2043 3310
+3310 2042
+3311 2647
+3312 2647
+3312 3311
+468 3000
+468 3313
+3000 3313
+1653 3314
+1652 3314
+3315 527
+3316 3315
+3316 527
+314 3317
+355 3317
+806 3318
+805 3318
+3319 3320
+1416 3320
+1416 3319
+2354 2640
+638 2354
+638 2640
+1922 3321
+3322 3321
+3322 1922
+1617 2717
+2717 838
+3323 3324
+3323 3325
+3324 3325
+3326 23
+271 3326
+2451 3327
+1662 3327
+2358 2236
+2358 2235
+1122 3328
+2583 1122
+2583 3328
+970 3270
+3329 970
+3329 3270
+2166 1873
+2167 1873
+1147 3330
+3330 2127
+3331 3332
+3331 3333
+3333 3332
+1524 3099
+3334 948
+2535 948
+2535 3334
+3335 3310
+1301 3335
+1301 3310
+3266 2979
+3336 3266
+3336 2979
+2550 3337
+2548 3337
+2382 3338
+3339 2382
+3339 3338
+3340 2283
+3341 3340
+3341 2283
+3342 3343
+3344 3343
+3344 3342
+3345 2232
+3345 2313
+2232 2313
+3346 1753
+3347 1753
+3347 3346
+3348 3349
+3350 3349
+3350 3348
+3351 2507
+3352 2507
+3352 3351
+3353 3354
+1225 3354
+1225 3353
+400 3355
+3356 400
+3356 3355
+3357 2959
+3357 2960
+1418 1497
+3358 3359
+3253 3359
+3253 3358
+3360 445
+3360 3361
+3361 445
+3362 3363
+3362 1084
+3363 1084
+2287 309
+3364 1335
+3364 2125
+2228 1388
+2226 1388
+2378 3365
+3366 3365
+3366 2378
+3367 1348
+954 3367
+954 1348
+976 352
+20 3368
+2811 3368
+3260 1335
+3260 1336
+1345 812
+1345 939
+503 2896
+503 3369
+2896 3369
+3370 3371
+3370 1728
+3371 1728
+3 2461
+2461 2
+3372 225
+3372 3058
+3373 3071
+3373 3070
+433 1835
+433 406
+3374 2316
+3374 836
+1394 3375
+2412 3375
+2412 1394
+3376 1647
+3376 1366
+1094 3377
+1094 2223
+2223 3377
+3378 2070
+3378 3379
+3379 2070
+3380 3381
+1607 3380
+1607 3381
+894 1940
+2548 1940
+2094 3287
+1380 2094
+3382 3383
+3384 3382
+3384 3383
+3385 746
+3385 3386
+3386 746
+2939 3387
+3387 2938
+3331 444
+3388 3331
+3388 444
+1841 2654
+758 3389
+3390 3389
+3390 758
+3391 1170
+2321 3391
+3392 38
+3392 37
+3393 3064
+1135 3064
+1135 3393
+3394 3233
+3395 3394
+3395 3233
+344 98
+2610 3396
+2610 1932
+3396 1932
+3397 1437
+3397 2151
+1437 2151
+1682 1221
+2924 3398
+194 3398
+1543 285
+3399 1543
+3399 285
+565 177
+175 565
+2312 3350
+3350 2502
+416 769
+3400 3401
+3402 3401
+3402 3400
+2449 1452
+587 2449
+2950 3403
+669 3403
+669 2950
+3404 3405
+3406 3405
+3406 3404
+1311 571
+3407 1307
+3407 3408
+1307 3408
+3409 1623
+3409 3195
+3195 1623
+3410 1493
+3410 1492
+460 839
+458 839
+2321 206
+3391 206
+3411 892
+3411 2045
+2045 892
+2513 1076
+3412 1076
+3412 2513
+2631 1081
+3413 1497
+393 3413
+3414 3415
+2769 3415
+2769 3414
+1252 3416
+3416 1251
+2916 665
+2499 682
+2499 681
+3417 1762
+3417 1761
+455 1644
+1745 1644
+2389 651
+3418 2389
+3418 651
+3419 1218
+3419 182
+2276 3420
+2130 3420
+2130 2276
+3421 2865
+3421 346
+2930 3422
+2930 3423
+3423 3422
+1446 3424
+3425 1446
+3425 3424
+3426 3363
+3362 3426
+2903 1879
+2903 1880
+2411 3427
+3427 2412
+3428 3429
+3428 3430
+3430 3429
+2679 3166
+2679 3431
+3431 3166
+3432 2409
+3433 2409
+3433 3432
+83 337
+339 83
+2490 560
+3434 464
+2965 3434
+2965 464
+3435 3436
+3437 3435
+3437 3436
+2842 3438
+3439 2842
+3439 3438
+2023 2624
+568 768
+3440 2038
+3440 3441
+2038 3441
+1397 233
+1395 233
+2195 3442
+3443 3442
+3443 2195
+3444 3445
+3446 3444
+3446 3445
+3447 1923
+1924 3447
+3448 2156
+3448 2157
+1949 1645
+1745 1645
+2485 3367
+954 2485
+3131 1795
+3131 2951
+2951 1795
+3360 446
+3384 1063
+1893 3384
+1138 2190
+1541 1138
+1541 2190
+1036 3449
+3450 1036
+3450 3449
+3451 3452
+3451 3453
+3453 3452
+992 3454
+991 3454
+2115 3429
+2116 3429
+2754 2331
+2754 2332
+3455 2195
+2029 3455
+2084 1923
+2084 1922
+2328 1582
+2330 1582
+3456 1459
+1460 3456
+1325 1220
+1325 1221
+3457 3458
+3457 544
+3458 544
+3459 3460
+3459 3461
+3460 3461
+3462 3463
+3464 3462
+3464 3463
+3465 3466
+3465 3181
+3466 3181
+3467 3468
+394 3467
+394 3468
+2402 2384
+3469 3470
+3471 3469
+3471 3470
+2579 3472
+3473 3472
+3473 2579
+3474 1410
+1014 3474
+1014 1410
+3475 3476
+3475 3477
+3477 3476
+3478 2736
+2290 2736
+2290 3478
+1561 3479
+1833 1561
+1833 3479
+3480 3481
+3480 3482
+3482 3481
+3483 879
+3484 3483
+3484 879
+3485 3486
+2679 3486
+2679 3485
+3487 3488
+3487 3489
+3489 3488
+3490 3327
+1770 3327
+1770 3490
+1132 945
+1132 944
+3152 616
+615 3152
+483 1008
+1008 482
+3491 2397
+3492 2397
+3492 3491
+1515 3493
+1516 3493
+130 3494
+3494 2872
+2795 2315
+185 3495
+2947 3495
+2947 185
+3496 3497
+3496 3498
+3497 3498
+866 1548
+2332 1548
+2332 866
+1867 3499
+1867 3040
+3040 3499
+3500 3501
+3500 2655
+3501 2655
+3502 3503
+3502 590
+590 3503
+3504 749
+3504 3505
+749 3505
+918 3506
+3507 3506
+3507 918
+3165 2679
+3165 2678
+2241 844
+2241 617
+1763 3508
+1763 1296
+1296 3508
+3509 1460
+3509 3456
+3510 3108
+3511 3510
+3511 3108
+3512 3297
+3296 3512
+266 2076
+2175 3164
+1305 3164
+1305 2175
+3513 3514
+3513 3515
+3514 3515
+3516 760
+3516 1028
+760 1028
+3081 2481
+3081 38
+2481 38
+264 2235
+2235 986
+3002 1166
+3002 1811
+2366 2678
+3165 2366
+3517 2196
+783 2196
+783 3517
+1067 3033
+1066 3033
+3518 2249
+3518 1761
+3519 3520
+3519 1625
+3520 1625
+3521 551
+3522 551
+3522 3521
+1491 939
+1492 939
+1045 3523
+2246 3523
+2246 1045
+1633 810
+2874 3313
+2874 818
+3313 818
+3083 372
+3361 3083
+3361 372
+2838 3524
+3525 2838
+3525 3524
+841 2208
+1435 841
+1071 1849
+2252 1071
+2252 1849
+2350 1939
+3239 2350
+3239 1939
+1607 1108
+3526 1108
+3526 1607
+1223 567
+567 2363
+2732 3527
+44 3527
+1752 3528
+3528 2387
+3529 2933
+3530 2933
+3530 3529
+3531 1651
+1649 3531
+1856 1512
+1856 3532
+3532 1512
+3139 261
+261 516
+3533 3534
+3535 3534
+3535 3533
+825 3384
+825 3383
+1394 1776
+1392 1776
+314 802
+3536 802
+3536 314
+1120 3537
+1151 3537
+637 2824
+3487 3538
+3191 3487
+3191 3538
+2791 228
+2434 228
+2434 2791
+2529 219
+3539 3540
+3539 3415
+3415 3540
+2114 3541
+3542 2114
+3542 3541
+2642 1484
+2642 3543
+1484 3543
+1869 334
+1868 334
+43 1944
+3544 43
+3544 1944
+2989 3545
+2989 3546
+3545 3546
+2973 2848
+2973 28
+3547 3548
+3549 3547
+3549 3548
+3550 120
+118 3550
+1818 3551
+3552 1818
+3552 3551
+2511 3553
+2511 3554
+3554 3553
+3505 2501
+3505 2500
+1574 1610
+3555 1118
+1119 3555
+3556 3557
+3558 3556
+3558 3557
+1212 243
+2662 1555
+2662 853
+1219 3529
+1066 3559
+3559 3033
+3560 2900
+3560 817
+2900 817
+3561 3562
+3561 1896
+3562 1896
+3496 1500
+3498 1500
+3563 977
+3563 976
+1264 2849
+3564 1264
+3564 2849
+1536 1475
+1536 1474
+1960 719
+1960 718
+3565 3566
+3565 3567
+3566 3567
+3568 3569
+3570 3568
+3570 3569
+2130 2275
+3571 3572
+253 3571
+253 3572
+3573 3574
+3411 3573
+3411 3574
+2514 77
+60 77
+2723 3575
+2188 3575
+3576 3577
+3576 3578
+3578 3577
+225 410
+831 3449
+831 1036
+2357 2236
+195 1969
+195 1968
+91 3153
+3579 3580
+3579 3581
+3581 3580
+1139 2190
+3582 420
+3582 819
+688 3583
+687 3583
+3584 3585
+925 3585
+925 3584
+237 2513
+3543 2643
+3586 3587
+3588 3587
+3588 3586
+2883 3589
+3590 3589
+3590 2883
+3591 3592
+3591 1458
+3592 1458
+798 2171
+798 3593
+3593 2171
+3594 3595
+3596 3594
+3596 3595
+2737 3597
+2736 3597
+3229 2022
+3229 3598
+2022 3598
+1121 3599
+3308 1121
+3308 3599
+1426 3483
+1426 3600
+3483 3600
+3601 34
+3601 2740
+1882 1430
+1882 3602
+3602 1430
+1139 684
+3603 3604
+3603 467
+467 3604
+3605 2120
+3605 461
+2411 3606
+3607 3606
+3607 2411
+3466 3608
+3466 1300
+3608 1300
+1328 1689
+1689 2429
+1608 920
+3609 3610
+607 3610
+607 3609
+3074 2793
+726 1921
+3611 373
+371 3611
+3549 1759
+3549 3234
+1759 3234
+2522 2344
+2522 2343
+3612 3613
+3612 1964
+1964 3613
+1828 2423
+1828 2496
+2423 2496
+2154 426
+2155 426
+3614 573
+3615 573
+3615 3614
+2801 3616
+2801 3617
+3617 3616
+1987 1397
+1987 3618
+1397 3618
+2296 2338
+409 2338
+2100 2305
+3619 2305
+3619 2100
+3620 3621
+3620 3622
+3622 3621
+1157 2912
+2912 1156
+3136 3623
+3624 3136
+3624 3623
+1524 2285
+3625 401
+1203 3625
+3300 2383
+3202 3300
+3291 2187
+3626 2187
+3626 3291
+3232 3627
+3627 3233
+3628 2374
+3628 2373
+3629 990
+3629 3630
+3630 990
+3631 1968
+195 3631
+2598 2867
+3555 2918
+3555 2465
+2465 2918
+1163 3632
+1162 3632
+2696 806
+3633 806
+3633 2696
+3634 1823
+3634 2831
+2980 3635
+2979 3635
+3591 1549
+3591 2332
+2332 1549
+190 2029
+2534 3636
+2008 3636
+3637 1076
+2588 3637
+2588 1076
+2753 482
+2940 3638
+2941 3638
+2618 337
+2618 849
+3639 3640
+3639 3641
+3640 3641
+496 2279
+2279 1286
+3642 3643
+1936 3643
+1936 3642
+3644 1761
+3417 3644
+3645 1561
+3645 1562
+3473 3646
+3473 2672
+3646 2672
+3647 3648
+3647 3649
+3649 3648
+3650 3038
+441 3650
+441 3038
+3651 2117
+3651 1073
+1073 2117
+3652 2325
+3653 2325
+3653 3652
+2406 3654
+2407 3654
+3347 1428
+3347 3655
+1428 3655
+2797 872
+2797 2441
+2441 872
+2064 1605
+1605 358
+1693 2869
+1691 2869
+2181 3656
+3657 2181
+3657 3656
+3272 1542
+3272 142
+1542 142
+2004 18
+1416 3622
+2634 1416
+2634 3622
+1402 1068
+1401 1068
+2115 3430
+618 575
+619 575
+3031 1221
+1325 3031
+3658 2959
+3357 3658
+2457 2607
+1569 2457
+2565 848
+498 3659
+3660 498
+3660 3659
+1197 3661
+1196 3661
+2582 1953
+3662 1953
+3662 2582
+3663 3664
+3663 3151
+3151 3664
+3665 3355
+3666 3355
+3666 3665
+2147 3667
+2147 3439
+3439 3667
+3231 3668
+3669 3231
+3669 3668
+3670 3503
+3670 3502
+1146 3671
+1147 3671
+3672 3673
+1026 3672
+1026 3673
+3674 3675
+3624 3675
+3624 3674
+3676 2932
+1219 3676
+3592 3595
+2333 3595
+2333 3592
+2006 1025
+2104 1917
+3677 3678
+1751 3678
+1751 3677
+1677 2957
+1677 2614
+2957 2614
+2302 2966
+2302 3679
+3679 2966
+3 257
+257 2461
+3680 56
+3681 3680
+3681 56
+312 1798
+312 40
+3682 241
+243 3682
+3489 734
+3683 734
+3683 3489
+3684 3685
+3684 1487
+1487 3685
+371 27
+3686 27
+3686 371
+3687 1673
+3687 1672
+3168 1320
+849 3168
+849 1320
+3299 3117
+3688 3117
+3688 3299
+258 3689
+3689 306
+2870 3597
+2386 3597
+3690 2700
+3691 2700
+3691 3690
+3692 3060
+552 3060
+552 3692
+3643 1532
+1393 3281
+1393 3693
+3693 3281
+412 2595
+474 412
+474 2595
+3694 2038
+3694 3440
+3695 973
+3695 1098
+726 3696
+3697 726
+3697 3696
+1088 3698
+3316 1088
+3316 3698
+2282 2212
+2282 3699
+2212 3699
+2034 1777
+2277 2034
+2277 1777
+3232 3700
+3232 1291
+1291 3700
+2663 773
+3701 728
+3701 2484
+2484 728
+3631 2
+2461 3631
+3702 599
+3702 2103
+2103 599
+3305 3703
+3637 3703
+3637 3305
+3704 3523
+3704 3705
+3705 3523
+3706 1409
+3706 3707
+3707 1409
+3708 2329
+3708 3709
+2329 3709
+3710 3711
+3712 3711
+3712 3710
+457 889
+457 188
+889 188
+3713 1213
+3713 99
+2631 2995
+3714 3715
+3716 3714
+3716 3715
+2990 2787
+1890 2787
+1890 2990
+3717 2516
+3717 3267
+3267 2516
+1638 3718
+3718 1639
+3411 1520
+3411 1519
+3584 3719
+3584 924
+924 3719
+1502 1485
+302 3720
+3720 301
+696 2558
+3721 493
+3721 1340
+2766 1505
+1505 2765
+2670 3722
+3722 3137
+2820 1707
+1362 1707
+3723 3724
+3725 3724
+3725 3723
+2767 3726
+2161 3726
+1701 3256
+1701 2298
+3256 2298
+1083 3363
+1083 3727
+3363 3727
+1594 833
+833 1626
+3728 3729
+3728 716
+3729 716
+3730 3731
+1947 3730
+1947 3731
+3032 140
+2798 140
+2798 3032
+862 1293
+2596 1293
+2596 862
+3732 1817
+3732 1818
+2279 497
+3582 3733
+420 3733
+3734 3353
+3734 3354
+1292 3735
+3735 1383
+1448 3219
+2664 3736
+1463 3736
+3151 3257
+3663 3257
+1168 3690
+1168 3737
+3690 3737
+3738 1628
+3739 3738
+3739 1628
+2342 1838
+1055 2342
+3510 2843
+2842 3510
+1819 3551
+1620 1808
+3209 1808
+3209 1620
+3740 3741
+1330 3740
+1330 3741
+3742 3429
+3742 3428
+821 1864
+2517 821
+1186 218
+3166 1186
+3166 218
+1876 2432
+1491 1876
+1491 2432
+3743 508
+509 3743
+3744 3068
+574 3068
+574 3744
+2357 2260
+2357 3164
+3745 2647
+2648 3745
+2242 3746
+3714 3746
+3714 2242
+3747 1775
+3747 2724
+2724 1775
+3179 2881
+3179 239
+2881 239
+3748 3749
+3748 3278
+3749 3278
+1697 3750
+1696 3750
+2520 47
+735 2520
+3751 3278
+3751 3749
+1496 3368
+1496 3752
+3752 3368
+2278 2633
+2278 3753
+3753 2633
+3009 2850
+3007 2850
+634 3754
+1715 3754
+1715 634
+3755 3525
+3756 3755
+3756 3525
+3757 2819
+3757 2884
+2611 3758
+2611 3759
+3758 3759
+3760 3750
+3760 3189
+3750 3189
+3761 3762
+3761 2323
+2323 3762
+3763 3764
+2574 3763
+2574 3764
+1450 3140
+3748 3140
+3748 1450
+1658 2876
+1658 3765
+3765 2876
+3766 3767
+1604 3766
+1604 3767
+3189 3768
+3769 3189
+3769 3768
+2998 2261
+2998 2262
+2311 1131
+2311 3770
+3770 1131
+23 363
+2652 2452
+1887 2790
+3771 2790
+3771 1887
+3772 3320
+3772 2832
+2832 3320
+3773 3774
+3773 800
+800 3774
+2951 3775
+3131 3775
+3776 2218
+1901 3776
+3159 3372
+3159 3058
+2301 3182
+2695 3182
+3777 1046
+3777 2621
+2050 3778
+3018 3778
+2482 2186
+2483 2186
+1185 3166
+3779 3780
+3779 1675
+3780 1675
+1433 1102
+3390 1102
+3390 1433
+313 3781
+3226 313
+3226 3781
+163 1385
+163 1386
+2987 1049
+3248 3782
+3507 3248
+3507 3782
+2421 599
+3702 2421
+2202 3361
+169 3508
+170 3508
+3783 3784
+3541 3784
+3541 3783
+1974 3785
+2007 3785
+3786 961
+3786 1908
+3787 565
+175 3787
+2969 3788
+3788 2968
+3789 589
+3789 2835
+589 2835
+3790 1641
+3790 2267
+1641 2267
+3791 3685
+2939 3791
+2939 3685
+1678 2943
+2943 1679
+1344 2456
+3792 3334
+3792 3793
+3334 3793
+267 3794
+1893 3794
+1893 267
+3795 2963
+3796 2963
+3796 3795
+2967 3797
+2967 1731
+3797 1731
+1770 196
+1768 196
+2130 3466
+3466 3420
+3798 3520
+3799 3798
+3799 3520
+1465 1160
+1465 3800
+1160 3800
+3801 649
+3801 3802
+3802 649
+1732 1940
+1732 65
+1940 65
+2475 3501
+2575 2475
+2575 3501
+1204 983
+3056 1204
+2687 1517
+2687 1515
+222 3395
+222 3803
+3395 3803
+3574 1040
+1520 3574
+1520 1040
+186 3804
+3697 186
+3697 3804
+49 3805
+1241 3805
+1241 49
+1295 1996
+1295 1997
+2107 3806
+3807 2107
+3807 3806
+648 1455
+3808 1057
+1058 3808
+3210 2892
+1073 3809
+3651 3809
+3183 2341
+2341 3184
+1443 867
+865 1443
+1746 3461
+2229 1746
+2229 3461
+2702 3810
+2703 3810
+3601 3811
+1234 3601
+1234 3811
+1379 3812
+3813 1379
+3813 3812
+701 3687
+701 1672
+1352 3814
+1352 3815
+3814 3815
+2703 3816
+3816 3810
+3211 1466
+436 3080
+435 3080
+117 3817
+117 2181
+3817 2181
+2653 3556
+2653 3818
+3556 3818
+3244 3600
+143 3600
+3819 1019
+3819 3820
+1019 3820
+1119 902
+902 3555
+1831 3140
+1836 1831
+1836 3140
+3821 220
+221 3821
+2003 2256
+174 2256
+174 2003
+2741 1503
+2741 927
+927 1503
+3822 3544
+3822 1944
+1062 2013
+3823 761
+3824 761
+3824 3823
+2932 303
+303 2933
+3825 526
+873 3825
+1533 2162
+1533 2164
+2357 2259
+268 2259
+268 2357
+448 3157
+504 3157
+3826 1021
+3826 1020
+2326 2042
+3827 542
+3827 974
+717 2254
+2076 2233
+2234 2076
+2144 2069
+2469 2144
+2524 2344
+3119 3828
+774 3828
+774 3119
+2742 325
+3829 3379
+3378 3829
+11 3830
+3830 3061
+933 3831
+3832 3831
+3832 933
+3833 3834
+3167 3834
+3167 3833
+247 3621
+247 3620
+3434 2807
+3434 2196
+1669 2992
+1669 2878
+2676 3521
+3835 2676
+3835 3521
+339 3836
+339 2177
+3836 2177
+3837 3091
+3837 3838
+3838 3091
+1860 3839
+3839 1861
+3840 943
+1477 3840
+1477 943
+3841 3664
+1125 3841
+1125 3664
+3516 2849
+3516 534
+534 2849
+3842 2362
+794 3842
+794 2362
+3843 3844
+3843 960
+3844 960
+3624 2272
+2272 3623
+1566 1023
+1566 1024
+955 1943
+955 1942
+2549 896
+2709 896
+2368 2774
+3845 2368
+3845 2774
+3774 3846
+3773 3846
+1424 3600
+3167 334
+952 3847
+950 3847
+1527 3848
+1527 2352
+2352 3848
+150 3849
+149 3849
+929 3168
+3737 2700
+3737 2701
+3850 3851
+3852 3851
+3852 3850
+1174 1635
+1174 1634
+3853 776
+3853 1237
+1399 813
+3410 813
+3410 1399
+3089 2238
+3854 2238
+3854 3089
+2359 1536
+3855 1640
+3855 1639
+2913 3856
+2913 3653
+3856 3653
+3857 312
+3857 40
+2787 1251
+2787 2515
+2515 1251
+3858 3648
+3721 3648
+3721 3858
+3762 3859
+3284 3859
+3284 3762
+3860 3861
+3860 3862
+3861 3862
+600 3087
+3086 600
+3863 2261
+1363 3863
+1363 2261
+2474 3274
+3864 2474
+3864 3274
+3865 987
+1085 987
+1085 3865
+3801 1662
+3801 3825
+1662 3825
+1597 1005
+1005 1596
+3866 3867
+3866 1511
+3867 1511
+3868 1962
+1961 3868
+288 3332
+287 3332
+2565 503
+3090 3854
+3090 1086
+3090 671
+1331 1781
+1781 1332
+1985 3869
+740 3869
+740 1985
+3594 3800
+3594 1160
+3870 1240
+3252 3870
+3252 1240
+2999 2013
+1495 2013
+2510 788
+3871 2510
+3871 788
+1714 365
+3872 1714
+3872 365
+1647 3873
+900 1647
+900 3873
+3874 3875
+1392 3874
+1392 3875
+3222 2281
+3221 2281
+3793 2059
+3334 2059
+3779 821
+3876 3779
+3876 821
+2711 3877
+2711 3878
+3877 3878
+2662 3205
+3205 2661
+3295 3879
+2049 3879
+2049 3295
+1940 3337
+3337 1390
+2578 830
+2578 829
+3448 1613
+21 541
+3167 1869
+1869 3833
+1433 3389
+3880 1754
+1898 3880
+1100 3719
+2655 3719
+2330 1584
+1371 3881
+3882 3881
+3882 1371
+1628 2607
+3883 2607
+3883 1628
+3884 3664
+3884 1746
+3664 1746
+480 3885
+480 3886
+3885 3886
+3372 1382
+3887 1382
+3887 3372
+3888 990
+3888 989
+3889 3890
+3563 3890
+3563 3889
+3891 1054
+3892 1054
+3892 3891
+633 3893
+633 502
+502 3893
+741 3249
+1012 3249
+3894 3060
+3894 2948
+2948 3060
+1195 3217
+1195 1448
+3217 1448
+3497 512
+2413 3497
+1208 2758
+1208 2976
+3642 85
+3643 85
+3895 1705
+326 3895
+3896 2543
+2542 3896
+1542 2040
+3357 3897
+3658 3897
+933 1232
+1609 1232
+3630 3898
+3630 3899
+3899 3898
+3900 3901
+3900 3494
+3901 3494
+3902 3161
+3902 1263
+3532 3903
+3904 3903
+3904 3532
+3132 3775
+1086 3132
+1086 3775
+109 3006
+109 3005
+3905 2165
+3905 3906
+3906 2165
+694 568
+694 768
+3907 2867
+3908 2867
+3908 3907
+1718 689
+1718 2239
+689 2239
+1972 2827
+1972 2829
+772 2784
+2170 3198
+3507 3909
+3782 3909
+880 523
+523 879
+3910 2210
+3911 2210
+3911 3910
+1803 3912
+3913 3912
+3913 1803
+2099 2136
+2099 3619
+3619 2136
+3701 3914
+3451 3914
+3451 3701
+826 2923
+3215 826
+3215 2923
+951 2774
+1192 951
+1192 2774
+3304 3915
+3304 3689
+3915 3689
+13 1133
+2405 3661
+2405 1196
+3313 3001
+71 3068
+574 71
+3316 2418
+3315 2418
+3916 3917
+3916 1494
+1494 3917
+296 1681
+46 1681
+3071 1176
+3071 1235
+1292 2719
+3290 2719
+3290 1292
+1860 3918
+1862 3918
+1083 986
+1085 986
+3423 3348
+3423 3349
+3193 2531
+1316 3193
+1316 2531
+3919 3819
+3919 3820
+1799 3920
+1799 3091
+3920 3091
+2436 989
+2438 989
+3921 2156
+3921 559
+3922 3218
+3217 3922
+3366 2955
+3366 3923
+3923 2955
+3561 3924
+3924 3562
+3923 2198
+2032 3923
+2511 2779
+3553 2779
+3925 2540
+3925 2635
+2635 2540
+3451 3926
+3701 3926
+1218 2164
+2164 2994
+1494 2250
+3916 2250
+3539 3927
+3073 3927
+3073 3539
+3928 3929
+3930 3929
+3930 3928
+3209 655
+3208 655
+3783 3931
+3784 3931
+969 3932
+967 3932
+3599 3307
+2084 3933
+2083 3933
+3625 3665
+3625 3355
+918 395
+3934 3935
+3936 3935
+3936 3934
+2090 1790
+56 3937
+3938 3937
+3938 56
+1584 2914
+1584 993
+2972 3080
+2566 2972
+3014 2374
+2374 3012
+2277 2633
+3867 3939
+925 3867
+925 3939
+3940 3098
+3940 1933
+1933 3098
+3941 2836
+2087 3941
+2087 2836
+3942 2759
+762 3942
+762 2759
+3943 3098
+3943 3940
+1876 1493
+1877 1493
+1306 3843
+2175 3843
+2175 1306
+3944 3576
+3944 440
+3576 440
+1251 3945
+3946 3945
+3946 1251
+3346 1645
+3346 1949
+481 3787
+2752 3787
+621 1976
+1978 621
+3947 3948
+3947 3949
+3949 3948
+283 2440
+283 2818
+1375 3740
+1374 3740
+2521 3950
+2521 3951
+3951 3950
+2326 3952
+2327 3952
+1751 3953
+3953 3678
+3548 2796
+3547 2796
+895 3534
+3954 3534
+3954 895
+3955 558
+3788 3955
+3788 558
+695 768
+1502 3087
+3087 1485
+3956 2848
+3956 437
+437 2848
+3957 3109
+3957 2299
+3109 2299
+2875 3772
+2875 3958
+3772 3958
+3919 2542
+3919 2544
+3959 3143
+3960 3143
+3960 3959
+3035 1639
+3718 3035
+1938 3239
+2630 127
+3961 2630
+3961 127
+1402 3481
+1068 3481
+3693 3116
+3281 3116
+302 2380
+3962 302
+3962 2380
+2811 3743
+3743 3368
+3963 3588
+231 3588
+231 3963
+3126 1144
+3778 2270
+3778 2203
+2203 2270
+3964 3422
+1526 3422
+1526 3964
+3965 3943
+3966 3943
+3966 3965
+3967 3968
+3967 3969
+3969 3968
+3536 3970
+3971 3536
+3971 3970
+3122 3972
+3122 3973
+3973 3972
+3974 3975
+3974 3235
+3235 3975
+3268 2762
+3268 3976
+3976 2762
+1677 293
+3795 1677
+3795 293
+1079 3180
+1079 3424
+3180 3424
+3372 226
+1634 427
+2705 1338
+2705 2496
+2496 1338
+3297 3604
+3977 3604
+3977 3297
+891 2879
+890 2879
+1214 3978
+2713 3978
+3979 3457
+3279 3979
+3279 3457
+3980 3981
+2237 3980
+2237 3981
+197 2173
+2462 2173
+2462 197
+3852 3982
+3850 3982
+3583 805
+688 805
+1881 3602
+3983 1954
+1122 1954
+1122 3983
+3323 1666
+3323 3162
+3984 3985
+3984 3986
+3986 3985
+474 2761
+418 3987
+418 2777
+2777 3987
+3988 3989
+286 3989
+286 3988
+3017 1840
+382 3163
+380 3163
+1519 3990
+3991 3990
+3991 1519
+3291 3976
+791 125
+3992 730
+3992 732
+3200 207
+3993 2645
+3994 2645
+3994 3993
+3995 3996
+3995 2603
+2603 3996
+1250 2893
+3150 2569
+2172 3150
+2172 2569
+3444 3997
+3296 3444
+3296 3997
+3048 2214
+578 1943
+3998 3999
+3998 4000
+4000 3999
+1982 4001
+1982 4002
+4001 4002
+4003 2651
+4003 2349
+2651 2349
+3979 1863
+3457 1863
+1016 683
+1016 2167
+2167 683
+4004 3401
+3402 4004
+3855 643
+3855 645
+1862 1508
+3528 1862
+3528 1508
+3914 4005
+4006 4005
+4006 3914
+1039 2721
+4007 1039
+4007 2721
+2964 3828
+3119 2964
+1897 3011
+4008 3789
+3245 3789
+3245 4008
+3484 4009
+3484 4010
+4010 4009
+4011 329
+4012 4011
+4012 329
+3224 2111
+2109 3224
+1669 3972
+3469 4013
+3469 3868
+3868 4013
+3315 4014
+3315 4015
+4015 4014
+2681 2845
+3066 2941
+2608 3066
+2608 2941
+3933 990
+2083 990
+3102 1065
+1065 3101
+3319 3622
+1577 996
+4016 3109
+714 3109
+714 4016
+713 4017
+4018 713
+4018 4017
+1945 2155
+1945 1368
+4019 4020
+4019 4021
+4021 4020
+2328 2073
+1582 2073
+3153 4022
+4023 4022
+4023 3153
+1285 3182
+2695 1285
+1467 1729
+1060 1467
+1060 1729
+3752 4024
+1496 4024
+2699 379
+2699 377
+3758 1321
+3759 1321
+2900 4025
+3560 4025
+2460 2625
+2090 2460
+4026 101
+4026 100
+2844 4027
+4027 2843
+1243 318
+2905 318
+2905 1243
+3 306
+313 1320
+1260 2642
+1704 2378
+2743 2378
+4028 2192
+4028 2194
+3333 3940
+4029 3940
+4029 3333
+1123 4030
+1123 4031
+4030 4031
+3544 853
+3822 853
+1887 4032
+3771 4032
+3644 4024
+1761 4024
+1535 2025
+1535 2162
+4033 1610
+2399 1610
+2399 4033
+1304 1480
+942 1477
+3308 3328
+1121 3328
+1376 588
+590 1376
+4034 1162
+4035 1162
+4035 4034
+4034 4036
+3149 4036
+3149 4034
+1565 1023
+844 827
+844 1289
+827 1289
+4037 2122
+4037 2123
+778 4038
+778 1967
+4038 1967
+4039 1544
+4040 1544
+4040 4039
+51 4041
+51 1857
+1857 4041
+3063 2442
+3063 3393
+3393 2442
+316 2905
+4042 3951
+4042 3950
+3813 4043
+212 3813
+212 4043
+3162 3324
+4044 2616
+3865 2616
+3865 4044
+903 2846
+4045 903
+4045 2846
+3225 3286
+3225 3287
+3723 4046
+3724 4046
+4047 4048
+4047 1033
+4048 1033
+765 4049
+764 4049
+2022 1283
+3229 1283
+4050 3933
+4050 990
+2519 3050
+4051 3050
+4051 2519
+3425 720
+3425 722
+3066 2111
+3066 2110
+1866 3040
+1866 491
+715 1929
+2765 715
+2765 1929
+2624 2093
+2623 2093
+2722 3173
+1552 3173
+2109 2892
+2877 1668
+2974 1668
+4052 3952
+3532 3952
+3532 4052
+250 1239
+252 1239
+783 3434
+3500 4053
+2720 3500
+2720 4053
+4054 1506
+3186 4054
+4049 4055
+3542 4049
+3542 4055
+4056 1812
+4056 1210
+2199 1468
+3886 2920
+480 2920
+992 856
+992 1583
+856 1583
+4057 4058
+4057 4059
+4058 4059
+863 2005
+16 863
+4060 4061
+4060 4062
+4062 4061
+3590 1388
+4063 2243
+3714 2243
+3714 4063
+2892 1734
+3825 649
+1615 1663
+2213 1663
+2213 1615
+747 3242
+748 3242
+1973 1645
+481 646
+483 646
+3707 3294
+3707 525
+3294 525
+3443 464
+3443 466
+2560 2567
+4064 2567
+4064 2560
+2634 4065
+2634 1453
+1453 4065
+2876 3958
+2772 2876
+2772 3958
+2894 3672
+1533 2994
+3461 4066
+3459 4066
+2771 1910
+2610 2771
+2610 1910
+4067 3847
+4067 952
+2527 220
+2527 219
+3649 2002
+2003 3649
+3901 4002
+3494 4002
+4068 3508
+4068 1763
+1154 4069
+2855 4069
+2187 101
+4026 2187
+33 763
+33 761
+3233 871
+4070 871
+4070 3233
+226 1382
+2081 226
+3139 259
+722 1446
+713 4071
+711 4071
+2953 4072
+3706 4072
+3706 2953
+157 4037
+157 2123
+4043 3812
+3516 1913
+3516 1914
+610 1851
+1018 2975
+1016 2975
+4073 426
+424 4073
+4074 736
+735 4074
+2902 2658
+2657 2902
+4075 3747
+3944 4075
+3944 3747
+3968 3460
+4076 3460
+4076 3968
+754 789
+3992 789
+3992 754
+3266 4077
+75 3266
+75 4077
+3794 4078
+3988 3794
+3988 4078
+25 3026
+419 25
+419 3026
+3301 1429
+3301 1427
+528 1088
+527 1088
+944 1631
+4079 1631
+4079 944
+4080 868
+4080 2474
+2474 868
+3982 4081
+3982 1787
+4081 1787
+3410 4082
+4082 1493
+991 3650
+3650 3454
+733 215
+1635 215
+3427 3606
+4083 2616
+4083 3865
+2132 2516
+386 2132
+3695 19
+19 1098
+4084 2733
+4084 2735
+729 182
+729 2624
+182 2624
+2737 3836
+2737 83
+3836 83
+299 4085
+3005 4085
+648 564
+648 4086
+564 4086
+3758 2612
+2311 4087
+707 4087
+3959 3142
+3196 57
+3196 55
+561 54
+3720 757
+2899 3831
+3832 2899
+3153 4088
+91 4088
+1874 4089
+1981 4089
+4034 4090
+1590 4034
+1590 4090
+4091 177
+176 4091
+4092 4093
+2406 4092
+2406 4093
+1649 2404
+1649 376
+2404 376
+3169 2231
+3695 2493
+330 3996
+330 4094
+4094 3996
+23 747
+1727 1467
+3977 3332
+288 3977
+3024 3082
+3024 4095
+3082 4095
+2372 965
+592 965
+3679 474
+3679 4096
+474 4096
+4097 3133
+2841 3133
+2841 4097
+2813 1287
+1285 2813
+4098 1212
+4098 1213
+1620 3079
+3868 3470
+1961 3470
+1888 2790
+1483 881
+1483 2424
+2538 4099
+3254 4099
+723 642
+723 4100
+4100 642
+882 4101
+3206 882
+3206 4101
+4102 3460
+4102 4076
+4103 911
+2108 4103
+2108 911
+1227 4060
+1227 4062
+928 1031
+3015 1031
+2491 2798
+3666 3188
+3666 3101
+979 965
+3845 2077
+3845 4104
+4104 2077
+2920 2478
+3696 4005
+4105 3696
+4105 4005
+3078 3398
+3078 2924
+3808 4076
+4102 3808
+4106 4107
+4106 3924
+4107 3924
+3973 2974
+1667 2974
+1667 3973
+1907 3374
+1907 836
+269 915
+4108 915
+4108 269
+3088 2654
+2654 3089
+3392 4095
+4095 38
+3991 1518
+4057 3929
+4057 3930
+2488 1244
+4109 2488
+4109 1244
+4110 4111
+4110 4112
+4112 4111
+1872 1758
+1872 2917
+2917 1758
+3552 3732
+3385 739
+3385 738
+3967 1783
+3967 1784
+4113 2320
+204 2320
+204 4113
+3700 3234
+4114 3700
+4114 3234
+1987 1396
+1986 1396
+4115 4116
+4115 3837
+3837 4116
+4117 590
+4117 3503
+3370 1727
+4118 2281
+3682 4118
+3682 2281
+3335 2043
+3531 4119
+1651 4119
+3841 1675
+4120 1675
+4120 3841
+4121 4072
+2953 4121
+4122 734
+4122 134
+1530 1331
+2655 4123
+3501 4123
+2768 3932
+2768 967
+2034 2943
+2034 3820
+2943 3820
+3356 3559
+3559 400
+4124 3535
+4124 3533
+4043 4125
+4125 3812
+3333 123
+3940 123
+4126 1989
+4127 4126
+4127 1989
+2646 4128
+2646 3351
+4128 3351
+1087 3698
+1295 3698
+1186 2829
+1187 2829
+1590 1025
+3065 1134
+1381 3065
+1381 1134
+4129 2701
+4129 2486
+4130 4131
+4130 10
+4131 10
+3322 4132
+3322 710
+4132 710
+1089 1526
+1089 3964
+1869 4133
+1870 4133
+1225 3734
+4134 981
+4135 4134
+4135 981
+496 411
+2659 411
+3676 1059
+2912 428
+2417 428
+4136 628
+4136 4137
+4137 628
+2896 2193
+4138 3365
+2033 4138
+2033 3365
+4139 3460
+3459 4139
+4140 4141
+3891 4140
+3891 4141
+1639 643
+1584 992
+20 1098
+4142 3849
+4142 150
+4143 869
+4143 4144
+869 4144
+736 3041
+4074 3041
+1528 2907
+1528 4145
+4145 2907
+507 2906
+4146 4147
+4146 1274
+1274 4147
+4148 168
+166 4148
+3783 4049
+3541 4049
+4149 3332
+3333 4149
+2407 1196
+1858 2978
+1604 3093
+3766 3093
+1595 604
+4150 604
+4150 1595
+893 3411
+893 1519
+4151 511
+4151 510
+1114 3525
+3525 1115
+2890 1654
+1934 3045
+1934 1309
+1309 3045
+4152 236
+235 4152
+2145 4153
+2147 4153
+1942 3452
+4154 1942
+4154 3452
+3096 4155
+807 4155
+807 3096
+2264 1953
+3662 2264
+1545 227
+2210 227
+1757 2740
+602 4156
+601 4156
+3044 3745
+1593 833
+834 1593
+4157 3891
+3892 4157
+4158 4066
+4159 4066
+4159 4158
+5 2171
+585 1453
+2331 3877
+2754 3877
+3650 4160
+991 4160
+4161 3359
+1342 4161
+1342 3359
+136 2460
+4162 2460
+4162 136
+4163 4164
+4163 2056
+2056 4164
+3962 4165
+3962 3720
+4165 3720
+97 3910
+343 3910
+1349 3021
+3021 651
+2802 714
+714 1929
+475 793
+50 475
+1437 587
+1437 586
+2925 4166
+324 2925
+324 4166
+2293 3575
+2723 2293
+1891 124
+1891 4167
+124 4167
+3957 2298
+3256 3957
+4168 565
+4168 564
+118 1111
+3550 1111
+4169 2253
+4169 447
+2253 447
+4170 2845
+2846 4170
+3908 2868
+1146 3041
+1146 3042
+2019 1993
+4171 2019
+4171 1993
+3663 1125
+2129 996
+1298 2129
+1298 996
+1458 3595
+1227 3734
+4060 3734
+3645 2026
+3645 3849
+2026 3849
+4172 1080
+4172 283
+3859 1372
+4173 1372
+4173 3859
+2517 4127
+4127 821
+1507 716
+1506 716
+1069 4174
+4174 2131
+3742 3264
+4175 3264
+4175 3742
+4165 757
+4176 4177
+2431 4176
+2431 4177
+3586 4178
+4178 3587
+2554 1753
+3346 2554
+4179 1333
+4179 1332
+2519 200
+4180 2197
+4180 425
+2770 1383
+3735 2770
+4181 3313
+4181 2874
+2452 258
+3915 2452
+3915 258
+2799 2399
+4182 3782
+3633 3782
+3633 4182
+1050 3688
+2157 2873
+2908 2157
+1127 3437
+2088 3437
+2088 1127
+4183 3511
+4103 4183
+4103 3511
+2128 3608
+3466 2128
+3526 3381
+4184 4185
+4184 4186
+4185 4186
+4187 3741
+4188 3741
+4188 4187
+4189 2371
+2370 4189
+579 4190
+577 4190
+1655 2068
+2119 1655
+4191 3878
+4191 3877
+162 318
+160 318
+4192 3727
+4192 3363
+1140 4193
+2244 4193
+2244 1140
+3377 1077
+886 1681
+886 1222
+452 959
+451 959
+1226 4194
+4195 4194
+4195 1226
+3502 4196
+3670 4196
+1621 2909
+1619 2909
+3641 2314
+292 3641
+292 2314
+2001 2184
+4197 2184
+4197 2001
+596 1389
+1389 2730
+140 4198
+3552 140
+3552 4198
+3123 2592
+3123 704
+4199 1236
+1614 1236
+1614 4199
+2995 4200
+2995 2584
+2584 4200
+2815 4201
+4202 2815
+4202 4201
+3481 1070
+1345 3985
+1347 3985
+4203 469
+4181 4203
+4181 469
+4204 4075
+3944 4204
+3364 2951
+3364 1795
+3578 440
+4205 3861
+4205 4206
+3861 4206
+4207 3318
+4207 4182
+4182 3318
+476 839
+690 839
+4208 1048
+4209 1048
+4209 4208
+3025 1340
+3406 1340
+3406 3025
+3802 1969
+1970 3802
+2497 2705
+3224 1466
+1466 2111
+3202 3339
+4210 4211
+4210 3710
+3710 4211
+3054 1748
+3754 1350
+4212 1350
+4212 3754
+3725 4133
+1869 3725
+4213 2864
+4213 934
+2349 3818
+4214 2349
+4214 3818
+1778 4079
+1778 4152
+4152 4079
+2535 3792
+2797 2442
+429 1634
+2466 1634
+2466 429
+3358 1503
+3359 1503
+2932 304
+1224 361
+1223 361
+3182 2813
+2360 2813
+3501 809
+2475 809
+1468 2656
+1469 2656
+3630 3888
+4215 4216
+4185 4215
+4185 4216
+3112 2829
+3112 2828
+4217 4218
+4217 3129
+4218 3129
+2326 3310
+2686 3712
+2686 3710
+4219 188
+4220 188
+4220 4219
+898 2410
+3432 2410
+3432 898
+2108 4221
+2107 4221
+2206 2313
+4222 280
+4222 3040
+4028 2800
+4031 4223
+4224 4223
+4224 4031
+1844 1472
+1844 1471
+4225 2062
+4225 2061
+2841 4226
+4227 4226
+4227 2841
+1769 3327
+2451 1769
+2691 1093
+1092 2691
+2598 3907
+3907 2640
+4228 4229
+4228 3176
+4229 3176
+2332 3592
+2494 781
+1888 2494
+4230 2725
+4230 2726
+3303 2573
+3303 3543
+2573 3543
+2671 3571
+3571 2670
+1034 406
+648 4168
+2255 2152
+2706 2152
+4231 384
+4231 383
+1373 4232
+4232 1372
+4233 4234
+4233 1885
+4234 1885
+95 3499
+1867 95
+2821 4235
+4236 2821
+4236 4235
+1495 3917
+4237 2928
+2927 4237
+1714 1783
+1797 776
+3449 84
+82 3449
+2801 2193
+1831 516
+2827 4238
+3042 4238
+3042 2827
+4018 3030
+4018 3029
+2518 1396
+4059 3897
+4057 3897
+386 3921
+3921 2132
+3174 153
+583 3174
+583 153
+1764 1478
+942 1478
+3765 2772
+705 3765
+4239 4240
+4239 4241
+4241 4240
+3183 2342
+126 4242
+4112 126
+4112 4242
+2363 2810
+756 2810
+3593 1229
+3593 721
+721 1229
+2949 2125
+4243 2949
+4243 2125
+3669 2342
+3668 2342
+4132 2508
+4132 404
+3549 2916
+2916 3548
+4244 3849
+2026 4244
+3936 2844
+3936 1441
+1441 2844
+4159 4139
+4159 3459
+2581 3692
+3039 442
+2322 442
+3948 1364
+4245 3948
+4245 1364
+1223 4140
+361 4140
+1674 1096
+1674 2551
+2576 1462
+1461 2576
+347 3398
+3078 347
+4087 4246
+4087 4247
+4246 4247
+4248 606
+2220 4248
+2534 2914
+1622 2914
+786 3254
+785 3254
+4249 1838
+4250 1838
+4250 4249
+4251 1797
+4252 1797
+4252 4251
+4253 879
+3483 4253
+1164 2776
+1970 4014
+1413 1970
+1413 4014
+1052 4075
+4204 1052
+2959 2013
+2249 2013
+4254 2443
+1288 4254
+341 4233
+341 1885
+1231 4255
+2447 1231
+2447 4255
+2743 2377
+1199 2377
+1199 2743
+1205 1794
+1205 4256
+1794 4256
+2544 4257
+2580 4257
+3251 4241
+3251 4240
+3388 4037
+287 3388
+287 4037
+4258 3924
+4258 4107
+4259 2062
+4259 4225
+4260 3610
+4260 2825
+3610 2825
+2656 390
+2956 390
+2956 2656
+696 4261
+4261 609
+3898 2437
+3888 2437
+3888 3898
+2903 4262
+2808 4262
+4110 2559
+4110 2560
+3880 3655
+3347 3880
+689 4263
+1718 4263
+960 451
+1306 960
+1306 451
+1861 4264
+1899 1861
+1899 4264
+3921 387
+387 2156
+3366 4265
+3366 2954
+4265 2954
+327 3895
+4151 4266
+511 4266
+1537 1475
+3588 2927
+3587 2927
+2124 26
+2124 25
+1915 3302
+1552 3302
+1855 1637
+1855 2863
+1016 2189
+472 2225
+4222 3522
+4222 2676
+2676 3522
+539 1123
+3046 539
+1806 3920
+4267 1806
+4267 3920
+4106 4268
+4107 4268
+4269 3156
+4269 449
+2419 1997
+2419 2467
+4270 3891
+4270 1054
+2711 4271
+3596 2711
+3596 4271
+1868 2685
+1868 2684
+4272 1412
+4272 1411
+4248 3609
+3609 606
+2570 34
+2570 36
+537 800
+799 537
+2908 4273
+4273 2157
+48 4274
+3029 4274
+3029 48
+2687 440
+3578 2687
+3676 4275
+3676 1994
+4275 1994
+4276 1480
+4276 3722
+1480 3722
+3326 2043
+3326 3335
+3373 4277
+3070 4277
+4278 723
+4278 725
+2225 3975
+3235 2225
+3836 2601
+4279 3581
+4279 3580
+1967 3365
+1967 4138
+3934 4027
+3790 4027
+3790 3934
+3716 3746
+4280 1942
+4280 1944
+724 4100
+1237 1921
+1801 4267
+4267 1807
+974 3145
+974 3144
+3032 3985
+2749 3654
+4281 3654
+4281 2749
+2722 3227
+2722 2854
+1298 4282
+3084 1298
+3084 4282
+2325 4160
+4160 2324
+48 2520
+4018 48
+4018 2520
+3409 4283
+3409 3856
+3856 4283
+31 2864
+31 2861
+2864 2861
+3050 2182
+2514 2182
+3068 4284
+3069 4284
+1184 3810
+1184 3816
+1766 521
+2644 521
+2720 1315
+2720 4285
+1315 4285
+2739 4272
+4286 4272
+4286 2739
+2554 2387
+2552 2387
+4287 1160
+1159 4287
+4288 1636
+4288 973
+1907 4008
+232 4008
+2962 4038
+1378 4038
+4289 3668
+4289 3231
+3486 4290
+3485 4290
+4291 4292
+4291 4178
+4178 4292
+3199 3096
+3199 4155
+4293 1249
+2234 4293
+4184 4215
+547 2144
+547 2142
+3835 3692
+3835 2581
+3936 796
+796 3935
+1600 1327
+1403 1600
+3660 7
+3660 499
+1614 2776
+2776 4199
+46 1682
+358 1109
+1606 1109
+1606 358
+3123 702
+3530 303
+2438 3888
+3615 4294
+3615 543
+4294 543
+3612 449
+3612 447
+914 4231
+2435 228
+2605 3046
+2213 4295
+468 4295
+2430 2593
+2430 2592
+2917 1759
+3549 2917
+3832 932
+275 1003
+277 1003
+3015 640
+3311 1151
+3311 3537
+2602 4296
+4296 1356
+3535 895
+2849 535
+1113 4297
+4298 1113
+4298 4297
+3598 41
+3598 2320
+41 2320
+666 2747
+666 2746
+3817 2182
+3817 3050
+4299 4300
+4299 4301
+4300 4301
+3868 4302
+4013 4302
+4303 2626
+4303 2459
+2459 2626
+540 391
+391 2906
+2040 285
+1363 2998
+4304 2812
+4304 2668
+3686 3560
+3686 4305
+3560 4305
+4186 4306
+2885 4306
+2885 4186
+3215 2474
+3215 868
+1586 4069
+202 1586
+202 4069
+1884 4307
+1883 4307
+1873 4089
+2293 3375
+3375 3575
+4296 1357
+3458 1863
+1632 909
+2074 909
+2074 1632
+4308 290
+310 4308
+310 290
+4309 716
+3729 4309
+525 4310
+3707 4310
+4311 2030
+2031 4311
+1624 3195
+3161 2930
+2929 3161
+3453 3914
+841 2721
+840 2721
+550 1323
+550 2948
+477 3011
+2856 477
+3874 566
+4157 566
+4157 3874
+1068 4174
+2997 3330
+4312 4170
+4045 4170
+4045 4312
+1671 4069
+2860 4069
+2860 1671
+1629 2607
+4313 1962
+1963 4313
+3412 1074
+4314 1889
+4314 2812
+192 3398
+1595 570
+603 1595
+584 778
+1378 778
+1520 4315
+1518 4315
+2991 4316
+4316 2515
+20 3752
+3159 403
+3159 1984
+403 1984
+261 187
+2315 2152
+2795 2152
+3612 1965
+1742 4317
+2300 1742
+2300 4317
+255 3571
+4318 2471
+3852 4318
+3852 2471
+324 4319
+322 4319
+3931 4320
+4321 4320
+4321 3931
+595 4292
+3445 4292
+3445 595
+4322 1406
+4322 1405
+3107 482
+943 3107
+1278 549
+1278 548
+519 3889
+3889 2925
+624 2945
+623 2945
+3051 4067
+3326 4323
+4323 2043
+1816 1729
+1815 1729
+4324 4325
+328 4324
+328 4325
+2839 229
+4288 229
+4288 2839
+3014 4326
+4326 3013
+4327 867
+4327 4263
+4263 867
+3564 2850
+3007 3564
+540 2030
+2030 541
+1440 361
+2787 2893
+2687 3712
+3712 1515
+712 675
+712 674
+4046 4328
+3723 4328
+3187 910
+3188 910
+4092 2215
+4281 2215
+4281 4092
+4329 3734
+4060 4329
+955 4330
+579 4330
+1130 1358
+3770 1130
+3770 1358
+145 2345
+4051 3656
+4051 3817
+3817 3656
+3133 3400
+4331 3133
+4331 3400
+2888 3381
+2336 3381
+968 4332
+3106 4332
+3106 968
+4333 1830
+1843 4333
+1843 1830
+2158 387
+2252 1837
+1814 3530
+1814 3529
+3502 795
+3137 4334
+3674 4334
+3674 3137
+3739 4335
+3739 4161
+4161 4335
+2866 3634
+1098 3752
+2179 3260
+2179 1336
+1762 3897
+4057 1762
+4336 1517
+3578 4336
+3578 1517
+4180 2920
+480 4180
+3570 3085
+3568 3085
+1063 4194
+4337 1063
+4337 4194
+3992 626
+3992 627
+3853 775
+594 4292
+4338 4187
+4338 3741
+538 4339
+537 4339
+3457 4201
+544 4201
+2292 4228
+2290 4228
+1996 4340
+4341 1996
+4341 4340
+367 1145
+1143 367
+4258 4268
+1636 2839
+1636 2838
+4342 3672
+4342 2894
+3921 1601
+1198 4343
+1197 4343
+4255 3034
+4255 2448
+2448 3034
+3963 158
+1161 4034
+4344 2486
+4344 2485
+3640 2935
+113 3640
+944 1130
+2533 1258
+2533 1260
+4345 1610
+4346 4345
+4346 1610
+2466 1998
+2667 3726
+3726 2668
+3514 3111
+753 3514
+753 3111
+4012 4152
+4347 4012
+4347 4152
+3295 4348
+3879 4348
+2363 2809
+1375 3741
+4338 1375
+345 4349
+2585 4349
+2585 345
+2596 863
+2596 2005
+4350 173
+172 4350
+74 3264
+74 3266
+173 2139
+2140 173
+3725 4055
+3724 4055
+3395 2592
+3123 3395
+4190 3815
+577 3815
+3056 2970
+3056 4156
+4156 2970
+2852 511
+1499 511
+1499 2852
+2110 2941
+4351 4328
+4351 4046
+814 3985
+3984 814
+2124 419
+1565 3405
+3406 1565
+1872 663
+1872 664
+2587 2963
+2586 2963
+49 475
+1859 4053
+3585 1859
+3585 4053
+4146 2171
+2758 989
+1275 1740
+1275 1739
+267 1894
+266 1894
+662 1784
+2515 3143
+4316 3143
+3698 1997
+4352 1429
+4352 3301
+3037 2324
+4353 3037
+4353 2324
+3210 3800
+4354 2805
+2806 4354
+3728 1506
+2431 1712
+1712 2432
+3686 3611
+4355 945
+1081 4355
+3023 4356
+1732 4356
+1732 3023
+3675 2272
+4357 4312
+4357 4170
+4358 3640
+4358 3639
+78 3817
+1843 561
+1843 54
+4359 2572
+4359 572
+2394 4360
+2394 4317
+4317 4360
+4361 2653
+3047 4361
+3047 2653
+3870 3358
+3870 335
+3358 335
+4362 4363
+4362 3227
+3227 4363
+3850 4081
+3511 4364
+4365 3511
+4365 4364
+4366 335
+3870 4366
+2202 445
+4367 795
+3502 4367
+921 1664
+1786 673
+3003 2328
+3003 180
+2328 180
+4039 4368
+4039 4369
+4369 4368
+4370 4158
+4371 4158
+4371 4370
+1525 4255
+2564 4255
+4372 1365
+4372 1366
+3425 4373
+3425 1792
+4373 1792
+2725 514
+4374 2725
+4374 514
+4375 4376
+548 4375
+548 4376
+3896 3321
+4257 3896
+4257 3321
+4058 3533
+4058 4377
+4377 3533
+857 4343
+1197 857
+1420 963
+1420 1980
+1980 963
+2856 839
+2197 2154
+782 2154
+782 2197
+4378 1499
+4378 1500
+3613 447
+2044 1576
+3387 1964
+3387 3613
+2773 2375
+1423 2773
+2014 2125
+2014 2126
+401 1959
+402 1959
+2448 4379
+4379 3034
+3627 3803
+3627 3395
+437 4380
+4381 4380
+4381 437
+4214 4382
+4382 3818
+1114 2838
+1636 1114
+3619 2306
+1530 1781
+1782 1530
+4224 4383
+4224 2847
+2847 4383
+122 2201
+444 122
+444 2201
+3273 2628
+3273 2627
+1802 3913
+4384 4385
+4384 4325
+4385 4325
+4386 3402
+4386 3400
+1192 1935
+4387 3477
+4388 3477
+4388 4387
+2565 3369
+2565 139
+3369 139
+1314 2428
+4389 1314
+4389 2428
+4390 1581
+4390 1580
+3338 2872
+3494 3338
+1262 332
+2742 2563
+1199 2742
+4391 616
+2885 4391
+4392 2219
+3998 2219
+3998 4392
+3558 3818
+1702 3408
+3408 3309
+3711 3250
+4210 3711
+4210 3250
+4083 987
+4112 2637
+2559 4112
+2559 2637
+1813 2551
+701 2551
+701 1813
+2922 4186
+2922 4185
+3367 4252
+728 4252
+728 3367
+2882 240
+1530 2882
+3756 3524
+4042 3756
+4042 3524
+3382 1063
+4393 2677
+4393 2676
+2401 4072
+2798 4072
+2159 3682
+2768 3682
+2768 2159
+210 941
+210 750
+4104 2658
+2369 4104
+2369 2658
+1820 1728
+1820 3371
+2557 2437
+2556 2437
+1377 2906
+4394 4395
+4396 4395
+4396 4394
+1592 28
+2973 1592
+2098 4106
+2098 3561
+4106 3561
+3609 4397
+4397 3610
+2109 2891
+4398 373
+4398 1575
+1585 3942
+2855 1585
+2855 3942
+1679 4317
+1679 4360
+4212 749
+3504 4212
+1744 149
+1744 1951
+149 1951
+4399 4400
+4399 1477
+1477 4400
+2579 2280
+2530 3805
+3837 3805
+3837 2530
+3728 4054
+4401 2
+4401 3631
+1392 3280
+1392 3281
+4402 55
+4403 55
+4403 4402
+1756 533
+531 1756
+503 4404
+501 4404
+607 2825
+1763 2825
+3961 2866
+3661 857
+3876 857
+3876 3661
+3858 4405
+491 3858
+491 4405
+1737 4194
+1737 4195
+370 147
+147 368
+3222 4118
+94 3022
+96 3022
+4406 1278
+4406 548
+1470 164
+3290 164
+102 558
+1773 390
+389 1773
+562 2940
+2940 1842
+3631 2937
+4407 3631
+4407 2937
+1733 4271
+1733 4408
+4271 4408
+2191 4409
+2535 4409
+4410 3096
+4410 3199
+3414 2606
+3414 670
+3791 3387
+4411 4412
+2047 4412
+2047 4411
+3966 3445
+3446 3966
+1310 2201
+4413 1310
+4413 2201
+3290 1912
+1472 1912
+2106 1553
+3237 1553
+3237 2106
+2899 2371
+2898 2371
+115 76
+4287 1618
+4287 1616
+2632 3677
+409 3677
+2563 4414
+751 4414
+4415 3689
+3304 4415
+2948 442
+1875 2433
+1875 2432
+4416 3503
+4416 3670
+3809 4417
+3651 4417
+2199 2956
+2956 2198
+2781 4054
+2781 4418
+4418 4054
+3723 4133
+4015 649
+3802 4015
+3256 4016
+3255 4016
+3979 3751
+3279 3751
+3732 4198
+3732 141
+141 4198
+2241 826
+826 2240
+3226 1320
+2780 2944
+4071 4017
+4419 4017
+4419 4071
+2787 2528
+2787 2869
+2528 2869
+2646 4420
+2646 4421
+4421 4420
+4422 709
+4422 1020
+709 1020
+4423 4424
+4423 1965
+4424 1965
+2484 3367
+4257 2543
+1461 3736
+2460 2092
+136 2092
+2530 1412
+2625 2459
+3129 2113
+4217 2113
+4425 4408
+4191 4425
+4191 4408
+3923 3365
+3994 4426
+2645 4426
+4394 1035
+1035 4395
+3850 4047
+4047 4081
+3084 1299
+475 3805
+1925 4286
+144 3600
+2908 2384
+2384 2872
+2990 791
+1890 791
+3505 2505
+3504 2505
+3693 630
+2309 4427
+2309 4428
+4428 4427
+4091 434
+433 4091
+809 4123
+4429 3675
+4429 2272
+4354 2984
+3147 2984
+3147 4354
+3454 4071
+856 3454
+856 4071
+2176 3408
+1307 2176
+4430 2947
+4430 4431
+4431 2947
+2626 2759
+2626 1790
+3465 3377
+3465 1094
+1575 933
+3330 3671
+1786 3671
+1786 3330
+3251 3493
+3251 4432
+4432 3493
+1427 4433
+4433 1428
+1449 4434
+4434 1245
+637 1939
+637 2350
+2783 4356
+65 4356
+1262 752
+3126 3246
+3795 155
+2963 155
+4435 4239
+1652 4435
+1652 4239
+2976 1207
+4109 4436
+2488 4436
+17 4437
+864 4437
+1633 2476
+4438 715
+1507 715
+1507 4438
+975 3145
+4424 3565
+4424 3156
+3565 3156
+291 3829
+2066 3829
+4439 2212
+4439 4440
+2212 4440
+3004 4254
+3004 1289
+4254 1289
+4441 4442
+4443 4442
+4443 4441
+4218 3128
+1891 2528
+1892 2528
+555 3828
+1204 4156
+483 647
+483 4444
+4444 647
+3296 4445
+3997 4445
+1900 1131
+4352 861
+3301 861
+2504 4240
+4446 2504
+4446 4240
+275 1004
+330 4325
+4243 1690
+2014 4243
+1142 1153
+3652 993
+991 3652
+3986 4447
+3986 3616
+4447 3616
+2176 1249
+3247 658
+3246 658
+4419 3030
+4017 3030
+3783 821
+1988 3783
+1988 821
+4379 2284
+591 4379
+4260 874
+4260 4397
+4397 874
+1335 1795
+4448 3017
+4448 1840
+2195 207
+2116 2195
+3951 4449
+2521 4449
+653 4450
+1450 4450
+4451 29
+30 4451
+1233 4452
+4452 1231
+4453 1684
+436 4453
+4454 2645
+3993 4454
+1534 3052
+253 4455
+4455 254
+2874 4189
+4456 1551
+1774 1551
+1774 4456
+3786 275
+3786 1004
+1694 2479
+2179 2479
+3593 1230
+2171 1230
+3706 4310
+4310 4072
+2104 2745
+2104 2526
+2730 4298
+1389 4298
+1446 2981
+722 2981
+962 568
+4457 962
+4457 568
+3910 4332
+4458 3910
+4458 4332
+694 4457
+3021 3275
+3019 3275
+3995 3118
+3995 1075
+4459 3843
+2174 4459
+2174 3843
+1789 2092
+3152 922
+81 201
+201 2795
+1116 4460
+1114 4460
+2428 1037
+3515 2428
+3515 1037
+3662 3094
+4461 2880
+4461 2881
+403 2509
+3871 403
+3871 2509
+3477 645
+4388 645
+3890 4319
+4166 3890
+4166 4319
+4462 4316
+2991 4462
+1191 1935
+1401 4297
+4463 1401
+4463 4297
+1624 2009
+81 202
+3932 2767
+1747 3664
+3926 2700
+2484 2700
+2484 3926
+99 1546
+97 1546
+2608 1910
+2887 1720
+4342 2821
+4342 1780
+3345 2641
+3345 2587
+2641 2587
+495 3208
+494 3208
+3388 446
+1750 4464
+4465 1750
+4465 4464
+1746 4066
+659 4066
+4304 4314
+348 4466
+1355 348
+1355 4466
+1736 4467
+1738 4467
+15 340
+340 14
+1117 2386
+4468 177
+563 177
+563 4468
+667 4307
+1659 4469
+4469 1660
+3978 850
+3978 337
+2226 995
+995 2227
+3190 4470
+4471 4470
+4471 3190
+4158 659
+876 4158
+876 659
+4472 1371
+1373 4472
+3705 4473
+4449 3705
+4449 4473
+880 3219
+880 3218
+2384 4474
+2384 4273
+4474 4273
+2695 1286
+1998 4341
+423 3288
+2729 479
+4475 479
+4475 2729
+3390 1914
+3919 4422
+2544 4422
+4476 3708
+2534 4476
+2534 3708
+1368 1871
+2737 2870
+75 1719
+4077 1719
+3159 3887
+4477 4478
+4479 4477
+4479 4478
+2078 3918
+1860 2078
+161 4480
+4481 4480
+4481 161
+4482 2036
+4482 4483
+4483 2036
+2226 604
+4150 2226
+3683 3488
+3683 3567
+3567 3488
+2734 3379
+2734 2070
+1880 4262
+4136 4262
+4136 1880
+3004 4484
+4485 4484
+4485 3004
+1476 4399
+4231 4402
+4231 3937
+4402 3937
+4486 4118
+4486 243
+243 4118
+2720 3764
+3500 3764
+1155 3567
+3683 1155
+1173 4487
+1202 1173
+1202 4487
+4365 2408
+2408 3511
+2605 4325
+2603 4325
+1086 3088
+4135 4488
+4489 4488
+4489 4135
+1426 4490
+4491 1426
+4491 4490
+2909 2924
+1619 2924
+4179 2821
+4236 4179
+2813 4492
+2812 4492
+3039 441
+2235 1083
+2235 3727
+421 1144
+3126 421
+4114 1571
+3700 1571
+1740 1365
+1013 1740
+1013 1365
+1941 1242
+1002 1242
+2215 2310
+2308 2215
+1192 3282
+3282 2774
+4269 4424
+602 1486
+602 1485
+4437 18
+4227 18
+4227 4437
+3871 787
+1588 1796
+492 1796
+492 1588
+4493 2629
+2628 4493
+3082 1598
+2783 1598
+2783 3082
+4003 1769
+1768 4003
+1945 1871
+1073 3278
+1072 3278
+4023 3765
+1658 4023
+3252 1239
+3012 506
+2480 1150
+1149 2480
+1376 4412
+588 4412
+2361 2977
+2362 2977
+3241 667
+4494 4220
+4494 4219
+4472 2052
+4472 2200
+1086 4495
+3088 4495
+364 4096
+4496 4096
+4496 364
+4406 4497
+4406 2698
+4497 2698
+3676 1032
+2932 1032
+4350 4498
+4499 4498
+4499 4350
+1434 2001
+1333 3400
+1333 3133
+1765 510
+1765 2413
+3786 2355
+2355 1004
+4294 3614
+3228 695
+1415 4423
+1415 1965
+4258 3768
+3924 3768
+1351 635
+4500 635
+4500 1351
+83 4501
+4501 84
+1962 4400
+4313 4400
+740 4502
+4502 3869
+4503 792
+2990 4503
+2990 792
+4371 3969
+4371 3968
+4367 1826
+795 1826
+1416 2832
+1296 3204
+3508 3204
+4282 996
+1577 4282
+3510 7
+4504 3510
+4504 7
+3049 785
+3049 4099
+785 4099
+823 4368
+4039 823
+1480 2644
+3722 2644
+978 2934
+4505 4506
+2147 4505
+2147 4506
+3018 2271
+3017 2271
+4507 1470
+4507 1719
+4352 4435
+4352 1652
+4429 2273
+4461 3179
+4461 3177
+3015 1319
+4190 4508
+4508 3815
+1941 1241
+3042 2134
+887 3042
+4509 4295
+1165 4295
+1165 4509
+2268 4065
+1453 2268
+3021 3276
+1349 3276
+3680 1546
+99 3680
+4510 2733
+4510 4511
+4511 2733
+305 674
+2071 674
+2071 305
+3150 2568
+2896 4512
+503 4512
+728 3914
+2402 4474
+4393 1334
+4393 2541
+2541 1334
+3569 4282
+4513 3569
+4513 4282
+980 4135
+2213 4509
+2694 2379
+3188 2379
+3188 2694
+2435 1046
+2435 3777
+3355 1281
+3356 1281
+2945 3207
+4514 1400
+2591 4514
+4504 1806
+2020 4504
+4385 4515
+4384 4515
+1553 3302
+3821 4516
+3821 4167
+4167 4516
+574 815
+71 815
+1796 3767
+1796 3766
+2458 4517
+3121 4517
+3121 2458
+3220 1179
+3220 1180
+2047 4518
+4518 4411
+4519 2907
+4382 2907
+4382 4519
+3572 2644
+2671 3572
+4520 4427
+2216 4427
+2216 4520
+3168 1417
+1136 2059
+1136 2058
+4521 909
+910 4521
+1815 3529
+4522 2836
+3941 4522
+4362 4354
+3173 4354
+3173 4362
+3207 61
+4131 1711
+4314 4131
+4314 1711
+4165 4523
+4523 757
+2719 1912
+4524 515
+4525 4524
+4525 515
+4526 3338
+3339 4526
+3761 3653
+3856 3761
+3716 3373
+3373 3746
+4527 3996
+4527 3995
+3980 4528
+3980 3540
+3540 4528
+2806 4362
+4529 4530
+4529 1587
+4530 1587
+4064 2396
+2561 2396
+2561 4064
+2693 301
+300 2693
+1351 3815
+1351 4508
+3120 1017
+3120 4303
+4303 1017
+1927 4531
+1927 3750
+3750 4531
+1779 3187
+39 2186
+2814 3278
+1073 2814
+4483 4532
+3778 4532
+3778 4483
+2623 2163
+2162 2623
+2570 87
+2571 87
+2361 2978
+4011 1809
+494 4011
+494 1809
+4533 4534
+4535 4534
+4535 4533
+2021 3598
+4192 916
+3426 916
+3426 4192
+2555 2000
+1999 2555
+81 1578
+1578 202
+574 4536
+4536 815
+4537 4538
+4539 4537
+4539 4538
+2351 1568
+2351 2638
+308 2744
+2586 1075
+3119 2586
+597 284
+597 2039
+3175 1064
+2897 4512
+4540 2897
+4540 4512
+4541 766
+1990 4541
+1990 766
+1593 2626
+4303 1593
+3933 1923
+1206 3238
+1206 2000
+878 3484
+4323 3242
+3848 4164
+4542 4164
+4542 3848
+1553 680
+3054 2512
+1748 2512
+2985 553
+2985 554
+2491 4543
+2489 4543
+1526 4542
+1527 4542
+4379 2286
+4053 2977
+364 499
+364 1105
+720 1792
+720 3593
+3593 1792
+1104 2936
+2936 1103
+4511 68
+68 2733
+3142 521
+2946 521
+2415 1950
+2415 349
+349 1950
+4352 1357
+4435 1357
+3691 4544
+4544 2700
+3866 1859
+3866 3585
+4511 2067
+2066 4511
+2280 3221
+4545 3383
+3382 4545
+4399 740
+4399 739
+1206 2757
+2756 1206
+4240 3249
+2504 3249
+86 1725
+1743 1725
+1262 4546
+752 4546
+423 4547
+4547 3288
+4548 4503
+4549 4503
+4549 4548
+4261 2558
+4261 2791
+2791 2558
+10 1346
+2697 3909
+3909 2751
+1748 3102
+3053 3641
+4550 4115
+3660 4115
+3660 4550
+771 154
+771 4551
+154 4551
+2627 833
+2629 833
+3680 3344
+99 3344
+4531 3886
+3885 4531
+314 3781
+2424 2476
+4552 27
+4552 26
+391 2046
+2046 892
+2303 2291
+4382 3558
+2279 4553
+4553 2278
+2921 2885
+2921 4186
+3702 4554
+3702 1722
+4554 1722
+3352 2766
+3352 2764
+4244 2027
+2523 4555
+613 2523
+613 4555
+2784 2716
+4556 2784
+4556 2716
+4205 2351
+4205 2638
+1101 2859
+1101 3228
+2859 3228
+808 2344
+4557 4558
+4557 3020
+3020 4558
+2791 4032
+3771 2791
+4387 3476
+4448 4387
+4448 3476
+1735 3199
+1735 2110
+2110 3199
+4429 4549
+4429 4548
+3880 1753
+3846 4339
+3846 2818
+4339 2818
+4382 4145
+1590 3149
+4230 3828
+1556 3828
+1556 4230
+4438 2765
+3192 133
+505 3192
+505 133
+3840 4302
+1686 3840
+1686 4302
+73 190
+3522 3499
+551 3499
+3201 2773
+1423 3201
+1687 3408
+4271 3878
+2553 1509
+2552 1509
+4070 3124
+4070 2441
+3124 2441
+3499 2366
+95 2366
+2864 2068
+124 4559
+4559 4167
+4560 4376
+4375 4560
+2779 63
+2779 2515
+917 270
+915 270
+812 3985
+4333 54
+1749 2952
+1749 4561
+2952 4561
+3158 403
+3826 403
+3826 3158
+2200 1371
+3882 2200
+1830 2537
+2537 3016
+1305 2357
+4396 4562
+3362 4562
+3362 4396
+1525 3034
+3181 4563
+3180 4563
+4564 706
+707 4564
+3493 3606
+3427 3493
+2430 2497
+2497 2593
+3329 2729
+3329 479
+388 4522
+4522 390
+1164 1614
+2575 3763
+3501 3763
+1395 3171
+679 3171
+2174 4565
+4565 4459
+2618 2851
+1579 2861
+3789 4411
+3789 4412
+4566 557
+4567 557
+4567 4566
+4324 2786
+495 4324
+2243 3481
+3482 2243
+3360 4552
+3360 26
+203 1586
+3203 977
+3203 4340
+4340 977
+3141 1326
+1404 3141
+2503 4446
+3083 373
+2699 4455
+463 4455
+463 2699
+2515 2946
+2112 4568
+2112 3834
+3834 4568
+2628 2473
+2007 2773
+3785 2773
+2207 4361
+2207 3047
+3894 2322
+3894 2319
+3300 2403
+2923 2240
+2921 2240
+2667 3932
+2667 2767
+2724 4569
+3747 4569
+1625 4570
+307 4570
+307 1625
+3433 2507
+2507 2409
+3073 2429
+3539 2429
+3765 706
+2082 3937
+2082 3938
+948 2059
+4373 3424
+4373 4563
+4563 3424
+2102 1245
+2408 7
+1198 1317
+1198 642
+861 1357
+1355 861
+3040 3522
+3718 4380
+1638 4380
+3900 3864
+3900 3274
+2663 2958
+2556 3736
+2556 999
+3736 999
+1061 1729
+916 1035
+4394 916
+2732 3239
+4571 4454
+4572 4454
+4572 4571
+3787 2259
+2752 2259
+1264 535
+3962 4573
+3509 3962
+3509 4573
+4317 4574
+2394 4574
+4104 3839
+3839 2658
+801 4575
+4403 801
+4403 4575
+1615 3115
+1615 1236
+1236 3115
+1255 4121
+1257 4121
+3526 4576
+4576 1108
+2864 1579
+1852 3413
+4311 3413
+4311 1852
+1528 3422
+1012 3250
+2609 4577
+2942 4577
+2942 2609
+4578 733
+4578 2925
+4324 4579
+4579 2786
+1033 4081
+478 4580
+477 4580
+3619 837
+1274 1740
+3755 1390
+4581 3755
+4581 1390
+1336 3546
+336 2674
+4582 2796
+2797 4582
+2153 201
+2153 2795
+2016 4580
+478 2016
+4583 2214
+3048 4583
+3399 4584
+1543 4584
+2565 2888
+2565 4585
+4585 2888
+4413 122
+4214 4519
+247 2269
+1908 4443
+1640 4443
+1640 1908
+4227 4097
+3621 4065
+2269 4065
+2269 3621
+1820 2053
+4586 1820
+4586 2053
+602 3087
+3186 4418
+2391 4418
+2391 3186
+3984 1398
+2799 4033
+1451 2389
+4493 2473
+3259 4493
+3259 2473
+2318 3881
+2317 3881
+2191 3257
+4191 4271
+1758 1570
+787 627
+1983 627
+1539 832
+1539 2629
+2629 832
+1182 3816
+4179 3400
+2902 1879
+1879 2658
+1710 4587
+1709 4587
+901 4588
+4589 901
+4589 4588
+2603 330
+418 3733
+3987 3733
+4129 3737
+2029 4590
+74 4590
+1890 125
+2152 2975
+2877 2152
+1348 4251
+777 1348
+777 4251
+2466 1174
+3432 897
+2427 3935
+2334 3935
+2334 2427
+2309 1747
+1747 4428
+4591 2926
+4591 4471
+4471 2926
+4134 4488
+3613 2253
+3791 3613
+3791 2253
+2327 3242
+3929 4478
+3929 2709
+2709 4478
+691 4592
+1482 4592
+1140 4473
+1142 4473
+2578 3036
+4593 3049
+4593 3048
+1657 247
+1657 3620
+4594 3479
+1831 3479
+1831 4594
+3416 3946
+1559 578
+1317 4343
+3500 3585
+4553 410
+4553 497
+2758 2557
+2436 2758
+2436 2557
+281 3440
+281 3441
+826 2243
+2243 869
+4510 2066
+4381 3718
+979 966
+2284 966
+1296 245
+3206 3909
+2065 816
+2065 576
+4137 4262
+2808 4137
+3664 1675
+2515 3945
+1129 2089
+1129 2088
+2925 652
+324 652
+753 331
+167 290
+167 4308
+3374 2835
+4595 4104
+3845 4595
+2859 2096
+4082 2897
+2895 4082
+2821 4596
+4342 4596
+2307 4597
+2307 3950
+4597 3950
+2949 3364
+4598 2637
+2398 4598
+552 3521
+3521 3692
+4599 4600
+4601 4600
+4601 4599
+1097 4578
+1097 4602
+4602 4578
+551 1353
+2294 3375
+3292 4603
+4604 3292
+4604 4603
+2161 3061
+12 2161
+67 311
+69 311
+2403 376
+257 2173
+2462 257
+1094 3420
+3465 3420
+268 4605
+4605 2259
+3901 3799
+3900 3799
+717 3013
+3840 4400
+4302 4400
+2166 4089
+4606 3236
+4606 929
+3236 929
+4607 1439
+1883 4607
+4091 4468
+2964 2586
+1068 3949
+4174 3949
+2562 2105
+3614 271
+271 573
+3781 3317
+1916 3781
+1916 3317
+4608 2248
+4608 2247
+587 1436
+2826 4380
+1638 2826
+4072 2400
+4511 69
+4511 311
+4088 4022
+4176 4512
+4609 4512
+4609 4176
+834 4216
+834 4215
+3864 3494
+3864 130
+798 1791
+1791 2427
+89 941
+90 941
+1284 4610
+3669 4610
+3669 1284
+4611 227
+4611 226
+4612 1442
+4612 2054
+1442 2054
+1903 3960
+1903 3959
+3478 3597
+3478 2386
+2588 2641
+1898 3655
+4594 4219
+3479 4219
+2909 655
+1621 655
+1265 2929
+621 79
+4225 3006
+3006 2061
+1200 4414
+4613 1237
+4613 1921
+3341 3699
+2282 3341
+4614 4615
+4098 4615
+4098 4614
+3391 2231
+3391 3169
+2347 4616
+93 2347
+93 4616
+4617 4618
+1550 4618
+1550 4617
+3978 338
+2894 4596
+1481 4596
+2396 2569
+2754 1444
+2754 4619
+1444 4619
+3979 2517
+3577 4569
+3576 4569
+3074 3168
+3074 2595
+3168 2595
+2817 3559
+4238 2828
+798 2146
+798 4146
+4146 2146
+3918 1508
+1127 3436
+1127 3366
+3366 3436
+67 1058
+126 4559
+4111 4559
+4111 126
+612 1952
+2697 1952
+1782 2882
+588 3789
+1303 4620
+4621 4620
+4621 1303
+1846 1464
+1845 1464
+2570 1531
+3001 819
+3001 818
+3455 3429
+2116 3455
+4622 1038
+4622 1039
+477 1897
+2690 215
+2487 935
+95 3165
+3305 2453
+3304 2453
+1318 857
+1318 859
+2391 3896
+4418 3896
+3464 1706
+3462 1706
+3070 1236
+2285 3257
+3099 2285
+3312 3044
+3312 3745
+3617 2193
+3314 4623
+4624 3314
+4624 4623
+1275 4480
+1739 4480
+3280 3875
+2197 465
+2197 464
+3663 4409
+2191 3663
+3093 4036
+3645 4142
+4142 1561
+3594 1458
+4625 3075
+4625 3790
+3790 3075
+4244 149
+450 262
+450 2236
+2660 4626
+2660 1794
+1794 4626
+4329 3912
+4627 3912
+4627 4329
+4070 3394
+283 678
+678 281
+3433 897
+4416 4196
+4588 3873
+4588 4147
+4147 3873
+4401 3684
+4401 1960
+1960 3684
+2082 384
+132 387
+1275 1099
+1275 884
+4451 2826
+4451 963
+1588 493
+2988 3299
+2987 3299
+2890 3655
+2890 1428
+4464 4628
+1749 4628
+1749 4464
+858 3879
+857 3879
+1562 4629
+3645 4629
+4359 3679
+2302 4359
+1201 2376
+1201 2377
+296 2650
+296 3148
+3148 2650
+3241 2463
+1931 3241
+1931 2463
+129 1900
+847 575
+2882 239
+2406 4281
+908 2463
+3450 407
+548 2142
+4375 2142
+3200 465
+2478 465
+4601 2931
+4630 4601
+4630 2931
+1462 2958
+1682 4274
+3031 1682
+3031 4274
+3883 2456
+1344 3883
+2245 4473
+3705 2245
+4035 2037
+2035 4035
+2349 2653
+45 854
+852 45
+446 26
+4123 4555
+4123 2523
+2785 4631
+2785 980
+980 4631
+3823 2759
+3823 2626
+3724 4049
+1254 2678
+23 4323
+46 4274
+2089 4632
+2087 4632
+3415 2606
+4451 3956
+30 3956
+4615 1213
+2579 830
+2349 2824
+4214 2824
+4574 2395
+3221 1180
+3269 2133
+3269 2762
+3694 1854
+3694 930
+1854 930
+1022 2958
+1022 1462
+1122 3537
+4633 3524
+3704 4633
+3704 3524
+567 2809
+2809 134
+4634 2702
+4634 3810
+2794 414
+3573 2045
+4481 2857
+4480 2857
+2115 3769
+3430 3769
+183 415
+157 418
+157 4635
+418 4635
+3444 4292
+4636 4292
+4636 3444
+4169 448
+4169 506
+3671 4637
+3671 3041
+3041 4637
+4445 4149
+3512 4445
+3512 4149
+1152 398
+1152 397
+3027 2220
+3027 4248
+2287 4002
+3901 2287
+1968 2937
+2657 3116
+3282 2657
+3282 3116
+3547 3234
+4519 2823
+1759 4114
+1572 4114
+3453 4006
+3668 1838
+4289 1838
+3866 3939
+3345 2206
+2969 1731
+3894 442
+3378 291
+4232 2052
+4232 4472
+2590 1922
+3104 4508
+3104 4190
+3750 1957
+3102 2512
+1125 4409
+174 2302
+4480 1099
+3803 1932
+4597 1391
+3141 1391
+3141 4597
+729 2704
+1355 4638
+4638 4466
+3329 2347
+2729 2347
+4391 4306
+2327 748
+2494 2790
+4285 1847
+3764 4285
+3764 1847
+2553 2375
+3269 2132
+774 3118
+1981 3905
+3905 4089
+1817 141
+1421 1508
+1421 3918
+2263 120
+2263 3190
+1602 4495
+1841 4495
+724 2970
+851 3681
+3665 2381
+3666 2381
+2262 4470
+2998 4470
+4134 1126
+4134 1124
+3430 4268
+4639 3430
+4639 4268
+1192 3875
+1192 3874
+2674 335
+4001 3338
+4001 3494
+1190 4514
+2010 3387
+2010 2938
+1718 4327
+4327 1716
+4640 4555
+4123 4640
+4087 4564
+4641 4562
+4642 4641
+4642 4562
+4383 801
+4383 2209
+2209 801
+3175 4013
+3175 3469
+1029 3128
+4218 1029
+4130 4643
+4130 4644
+4643 4644
+2764 1929
+2764 2507
+4029 4149
+381 3107
+381 1703
+3576 3747
+1627 3739
+4645 3739
+4645 1627
+4646 4578
+4646 2925
+85 3145
+975 85
+176 433
+4108 4192
+4108 916
+3333 444
+444 123
+1314 2720
+1314 1037
+712 735
+4269 1965
+3612 4269
+4028 1399
+2194 1399
+3003 2329
+3702 3130
+3251 4623
+4432 4623
+1156 3567
+2722 4362
+2647 3097
+4647 2647
+4647 3097
+1354 1220
+1354 1325
+3447 755
+1923 755
+3973 2975
+2203 770
+2584 2996
+3220 4357
+4357 1179
+2114 3784
+1535 770
+4648 1287
+3106 4648
+2785 1266
+4163 2352
+4163 3848
+899 1647
+1000 2437
+1000 2556
+57 2918
+71 3067
+1006 2684
+1240 2684
+1580 4575
+3196 4575
+2813 4648
+4648 4492
+4602 1813
+1210 4602
+1021 3158
+1560 2425
+2425 1561
+4649 482
+4649 3107
+2682 903
+445 2201
+1955 3983
+1179 4170
+1181 4170
+1086 3403
+2904 317
+316 2904
+1011 4171
+2348 4171
+94 1185
+4650 4368
+4650 823
+147 4138
+370 4138
+4407 2939
+4378 3498
+551 2365
+2365 1353
+932 2372
+4169 2254
+4651 3413
+4651 1497
+4373 1300
+1300 4563
+951 2775
+4082 1877
+4652 43
+4652 44
+4643 939
+4643 1491
+1527 2907
+2390 2766
+3352 2390
+1928 2409
+4193 2833
+2097 4193
+2292 4229
+1116 2708
+2550 2708
+744 1985
+1905 438
+1991 1905
+1991 438
+2801 3986
+3986 2800
+2300 3182
+2566 1592
+1591 2566
+582 4318
+4318 779
+1538 1882
+4209 731
+2577 4209
+4413 121
+1308 4413
+1308 121
+4645 4335
+2797 3065
+3063 2797
+3342 904
+904 3343
+188 456
+2234 2075
+2073 855
+1582 855
+4537 645
+4388 4537
+4253 4072
+4310 4253
+1344 3738
+1342 3738
+2747 4307
+666 4307
+3718 4453
+4381 4453
+92 4088
+4497 4376
+4406 4376
+625 4430
+625 4431
+888 2678
+888 2680
+1375 4653
+4338 4653
+2089 3999
+2089 4654
+4654 3999
+4655 2185
+4655 2186
+2541 1796
+3565 3488
+3565 3487
+205 2339
+205 2338
+4187 1003
+4188 1003
+4336 3577
+4336 2295
+3577 2295
+4093 3661
+2405 4093
+4656 2065
+4656 2064
+4657 2630
+4657 1082
+2842 4504
+2247 1080
+4658 2247
+4658 1080
+1577 4513
+90 4513
+2035 4036
+4035 4036
+1231 2506
+1231 1608
+418 2123
+419 2123
+2143 1693
+4546 2748
+1262 2748
+4350 414
+4350 413
+2092 137
+3563 518
+3889 518
+1191 1096
+1191 1674
+4469 2127
+4029 3943
+64 1598
+3212 4659
+3675 4659
+3675 3212
+52 3193
+52 2422
+793 3842
+2594 3842
+2594 793
+2110 2891
+114 4660
+112 4660
+4173 4232
+3648 3404
+3649 3404
+1559 2661
+4260 246
+4437 4226
+4436 1257
+4436 1256
+4286 3092
+4272 3092
+4279 2413
+4279 3497
+4591 119
+4291 4591
+4291 119
+1585 4069
+4608 654
+4608 1637
+7 3920
+4550 3920
+4550 7
+217 4290
+217 3486
+1297 4404
+4661 4404
+4661 1297
+4438 1505
+3796 2587
+3345 3796
+1329 1689
+2597 2005
+1172 3598
+3229 1172
+3607 4432
+4432 3606
+1417 2362
+2208 2362
+2208 1417
+546 4488
+546 4489
+4386 4004
+4159 4371
+4371 4139
+2416 4433
+3346 2416
+3346 4433
+2243 2185
+3482 2185
+3477 644
+3477 2665
+644 2665
+424 3065
+3065 4073
+3615 571
+825 4584
+3384 4584
+3162 4318
+1661 3162
+1661 4318
+3925 614
+614 2635
+3618 233
+3618 232
+4038 3365
+4329 3913
+3573 2047
+3573 4518
+2530 3091
+1412 3091
+1211 4602
+1211 4578
+1560 2426
+823 1544
+2490 1573
+2489 1573
+1201 4662
+1129 4662
+978 3203
+2121 254
+462 254
+1361 1299
+3084 1361
+4476 2914
+4476 1584
+2075 1720
+265 1720
+3760 3769
+2115 3760
+4489 4201
+4202 4489
+1158 4663
+1158 4664
+4664 4663
+3589 3097
+4665 3097
+4665 3589
+1624 1850
+1216 4315
+4666 1216
+4666 4315
+1783 366
+1783 365
+2373 133
+2373 135
+4304 10
+10 2668
+3928 895
+3928 3535
+4108 3727
+4667 3727
+4667 4108
+4346 1574
+1140 2245
+4239 4446
+4435 4446
+2657 2368
+1609 1231
+4479 4024
+4479 3752
+3110 1473
+1473 3109
+4451 1420
+4668 484
+4668 918
+918 484
+846 1605
+3199 3468
+2110 3468
+2255 2315
+914 4402
+3493 3711
+3251 3711
+4403 4669
+801 4669
+1789 137
+538 4515
+538 4172
+4172 4515
+1837 1071
+1963 739
+1963 3385
+385 1983
+3801 1969
+3801 3490
+3490 1969
+2450 4206
+2451 4206
+3036 3830
+3036 3061
+4670 3013
+4670 4326
+3594 4271
+3594 1733
+2583 1954
+4291 3587
+4591 3587
+152 3812
+1643 3812
+1643 152
+2483 399
+4655 2483
+4655 399
+1643 4671
+4125 1643
+4125 4671
+2444 3114
+2416 1949
+2416 1950
+2251 718
+1184 378
+377 1184
+4510 3829
+4151 1765
+942 4151
+3246 657
+3572 2645
+3572 4426
+1305 2236
+1632 1358
+3184 4085
+2341 4085
+3282 2368
+3678 2231
+2230 3678
+3761 2325
+1554 680
+272 1554
+689 459
+2956 3435
+3435 390
+3980 2238
+3344 3555
+3555 3343
+4232 4587
+2044 4232
+2044 4587
+3809 2814
+472 4672
+471 4672
+1548 867
+4603 1258
+4604 1258
+563 84
+563 4501
+4593 785
+1431 4661
+1431 1297
+114 4599
+114 4600
+4226 1090
+2841 1090
+381 4649
+380 4649
+636 4113
+634 4113
+1412 3092
+630 3607
+3693 3607
+4293 3135
+4293 4020
+4020 3135
+3642 975
+4264 1754
+1752 4264
+3558 4673
+3558 4145
+4145 4673
+3200 3442
+3200 466
+466 3442
+2266 3108
+1642 3108
+1642 2266
+1233 3103
+3651 3103
+3651 1233
+3959 1902
+4621 1902
+4621 3959
+2869 2069
+2070 2869
+3426 4396
+3059 2582
+3405 4674
+3405 803
+4674 803
+4491 3340
+4491 4329
+3340 4329
+4161 3738
+3473 82
+1596 569
+2355 1596
+552 2948
+4369 2283
+4368 2283
+4023 248
+2147 4146
+1151 2479
+3554 1384
+2511 1384
+2863 4675
+1855 4675
+4676 3041
+4676 4637
+1089 4164
+4164 1090
+2086 1533
+1986 3656
+4051 1986
+4571 2645
+4571 1766
+1564 802
+1564 804
+1602 3767
+665 3731
+665 3730
+3406 3648
+4475 2728
+4677 4142
+4677 4494
+4142 4494
+912 3174
+3967 4076
+780 541
+2799 4345
+2799 4543
+4345 4543
+3959 4620
+4678 4620
+4678 3959
+2875 3320
+1531 1756
+3292 3506
+3293 3506
+4465 3690
+1750 3690
+2707 4501
+4086 4501
+4086 2707
+4353 2323
+4353 1372
+2323 1372
+2552 1508
+2336 3526
+3526 560
+405 4132
+4548 2991
+4548 4462
+396 3467
+562 3467
+3977 3512
+3977 4149
+1998 517
+4341 517
+4452 4255
+4515 1080
+4650 824
+4650 4545
+4545 824
+3361 4552
+372 4552
+2176 3309
+2175 3309
+3095 3881
+3095 3882
+646 3787
+646 4168
+4168 3787
+1819 139
+1819 3369
+3500 3763
+735 675
+4384 4579
+4579 4515
+4679 1922
+3322 4679
+2858 2227
+994 2227
+994 2858
+4283 3762
+4283 3761
+2756 1208
+3995 1074
+3412 3995
+4439 3699
+151 912
+2714 4551
+2726 2714
+2726 4551
+492 2541
+1706 3863
+4680 3898
+4680 1000
+1000 3898
+1857 1510
+49 1857
+4634 378
+4497 4634
+4497 378
+748 4052
+364 4052
+1744 148
+4506 4147
+4146 4506
+491 3721
+2571 3643
+1327 1599
+64 1599
+4283 3284
+3289 3246
+3289 657
+4681 4682
+4681 581
+4682 581
+2741 335
+4058 3930
+2754 4191
+3822 1943
+3833 3725
+3716 3071
+4398 4025
+4398 3611
+3611 4025
+3858 3647
+3990 392
+893 3990
+893 392
+2875 3620
+3814 2505
+1352 2505
+1755 2570
+1755 1531
+2515 4683
+3554 2515
+3554 4683
+4684 4685
+4684 4539
+4539 4685
+2778 4686
+759 4686
+681 4616
+3225 4616
+1172 3230
+1171 3230
+4261 4032
+4261 610
+610 4032
+3824 1593
+3824 33
+33 1593
+907 2855
+1113 4687
+4688 1113
+4688 4687
+1845 1471
+1845 4663
+1471 4663
+1262 1135
+1659 3324
+1659 3162
+784 1995
+1995 785
+4689 1565
+4689 1564
+286 3399
+4633 3705
+277 4188
+4188 1328
+1420 1979
+1418 1979
+1180 2672
+3646 1180
+1200 4662
+3601 2141
+3181 3377
+4422 3819
+1288 940
+2840 940
+1560 2008
+2008 2426
+1426 2400
+4491 2400
+1027 4690
+1026 4690
+1141 2858
+953 2485
+4691 1615
+4691 1663
+2847 4223
+937 1851
+938 1851
+1222 1253
+886 1253
+726 4005
+1593 2070
+2735 2070
+2735 1593
+4692 2528
+4692 4167
+2528 4167
+431 3045
+1934 431
+323 3276
+3261 323
+1757 1301
+2326 1301
+2660 1555
+4416 4117
+3286 4616
+977 518
+4340 518
+4530 1789
+4452 2564
+3570 3077
+3570 3076
+2248 1853
+2248 1854
+4498 414
+2794 4498
+2194 4082
+4082 1399
+2987 4693
+3339 2987
+3339 4693
+2843 4694
+2265 4694
+2265 2843
+1059 453
+3658 4695
+4059 4695
+4059 3658
+1223 4141
+3489 4122
+1015 1410
+1015 162
+1263 3008
+2929 4601
+2929 4599
+1874 2744
+1483 1259
+1464 4663
+4058 4124
+3800 1734
+3210 1734
+4353 1371
+4353 3881
+2492 1511
+4347 4355
+946 4355
+946 4347
+3586 3298
+3586 3604
+3298 3604
+2922 4216
+4696 2922
+4696 4216
+4160 3038
+3748 1656
+2715 4697
+2727 4697
+2727 2715
+3156 3487
+3156 3191
+3006 1237
+4613 3006
+4417 3103
+2771 1911
+4410 2170
+4111 221
+4111 3821
+4698 4006
+3453 4698
+2290 2599
+2599 4228
+29 4699
+28 4699
+3283 1670
+3283 906
+1670 906
+4258 3430
+942 2224
+2224 482
+3570 4125
+3569 4125
+3773 4339
+3491 792
+1721 4700
+1722 4700
+2356 674
+4701 1156
+4701 3566
+3566 1156
+1758 1369
+1188 3176
+3777 228
+3214 4659
+3214 4316
+4659 4316
+4582 4702
+3548 4582
+3548 4702
+60 76
+4703 3130
+4021 3130
+4021 4703
+4649 2259
+1055 110
+1055 2340
+2340 110
+693 1144
+421 693
+840 4007
+4549 3491
+3491 4503
+4704 724
+4704 4100
+4597 4705
+4705 1391
+2673 4572
+4572 549
+1226 3354
+4246 3240
+3770 3240
+3770 4246
+2137 1896
+2969 3955
+3350 3557
+3348 3557
+1878 629
+1898 629
+4183 4221
+2108 4183
+1047 3524
+1047 2838
+1958 3562
+1895 3562
+1895 1958
+3359 1504
+4161 1504
+972 3752
+1905 2747
+1905 4307
+961 568
+2327 4052
+2789 289
+4545 4337
+4650 4337
+2987 4526
+2987 1138
+1138 4526
+2778 1481
+2778 1028
+2222 3027
+540 393
+3467 3638
+3468 3638
+4600 3641
+113 4600
+113 3641
+3990 2710
+2710 392
+4220 148
+4220 456
+148 456
+971 1114
+971 4460
+2207 2502
+3852 1661
+3352 4706
+2390 4706
+4273 4119
+4474 4119
+3955 2051
+3392 2051
+3392 3955
+2868 1293
+4323 747
+3142 520
+4707 4007
+4707 840
+3953 2230
+424 3270
+970 424
+2501 1144
+693 2501
+4329 3699
+3340 3699
+2746 4247
+666 4247
+4529 4708
+4530 4708
+397 1153
+3852 3330
+3982 3330
+1938 2597
+1938 3527
+3527 2597
+4477 2709
+3351 897
+3433 3351
+4150 1388
+3590 4150
+3154 1885
+3154 4234
+2878 1668
+2735 3151
+4184 3151
+4184 2735
+1672 2551
+186 4698
+4698 185
+2585 1620
+3489 3538
+2222 2456
+1918 1007
+1006 1918
+4450 652
+4646 652
+4646 4450
+4059 4377
+4377 4695
+422 3246
+3126 422
+2167 685
+2167 4709
+685 4709
+4102 1057
+4021 3135
+2886 4021
+2886 3135
+3455 4590
+1713 1431
+3947 4687
+3947 2820
+2820 4687
+2862 656
+4124 3930
+4124 3928
+4704 1486
+4704 602
+1450 1209
+1209 3140
+4487 319
+3553 2515
+523 3294
+4710 1039
+4710 4007
+4534 4016
+3255 4534
+4410 3198
+3743 1826
+795 3743
+4648 968
+4130 1346
+4130 1345
+3717 131
+1421 3201
+4711 3201
+4711 1421
+4712 802
+4712 3536
+4630 4600
+811 4640
+611 4640
+611 811
+3352 4128
+1814 2446
+3530 2446
+31 3283
+4652 4280
+4652 1944
+1312 543
+4713 1312
+4713 543
+4476 2329
+2967 375
+4421 2065
+4420 2065
+1498 4714
+1498 29
+4714 29
+3170 233
+2911 233
+2911 3170
+4088 2018
+55 3937
+4715 2559
+4715 2637
+4628 1942
+4464 1942
+1700 4716
+1701 4716
+4717 4718
+4714 4718
+4714 4717
+3493 2294
+3493 3375
+293 2614
+1089 4542
+3354 2400
+3734 2400
+1350 635
+398 4297
+2730 4297
+2730 398
+3826 405
+3993 1279
+3994 1279
+3662 3059
+1906 2490
+4581 3337
+2550 4581
+3908 1293
+4458 3106
+2911 234
+2263 3863
+2018 1993
+1932 2771
+431 1933
+421 692
+423 692
+1967 2470
+2571 85
+45 2649
+3515 4719
+3514 4719
+2276 4720
+4720 3420
+1774 3370
+1772 3370
+501 4721
+4721 4404
+3775 3403
+2447 2506
+582 1665
+4318 1665
+3574 1041
+3749 1656
+4589 2020
+4210 1012
+4210 1011
+488 4592
+488 691
+1204 4256
+3417 4478
+3417 3929
+1951 2364
+2364 1950
+2403 375
+3689 3055
+3054 3689
+2749 2971
+725 2749
+3055 306
+3055 3033
+4309 2395
+2393 4309
+1494 4024
+3282 3875
+2345 146
+2345 1468
+3450 434
+434 3449
+4374 4697
+4374 2727
+4063 1070
+3715 4063
+3715 1070
+3386 2316
+3386 2834
+3311 4647
+4665 3311
+4665 4647
+1149 2479
+2051 37
+4026 2051
+4026 37
+1449 1408
+3294 1408
+613 1952
+969 4648
+2232 3796
+2232 3795
+4722 2936
+4722 2935
+891 3687
+891 700
+700 3687
+1697 4531
+1981 4001
+4417 1266
+4421 4128
+1816 1010
+178 1816
+4692 4516
+4692 220
+220 4516
+4457 3258
+1708 1233
+3651 1708
+1059 1994
+430 1933
+849 2712
+850 2712
+3758 3970
+2612 3970
+4374 4524
+4524 4697
+2681 2385
+2683 2385
+1716 4723
+3003 4723
+4200 2865
+2866 4200
+2120 3623
+3627 1383
+2770 3627
+352 3262
+3261 352
+4668 3506
+4566 1613
+4566 3448
+4341 518
+4389 2422
+3944 439
+1855 930
+930 4675
+2792 3759
+2611 2792
+3538 3192
+90 210
+90 211
+4581 1115
+3755 1115
+1908 737
+3786 737
+3594 1456
+1160 1456
+4724 4340
+4724 1996
+4116 3659
+4725 4116
+4725 3659
+3450 408
+1328 3741
+3295 3127
+4525 2577
+4525 4726
+4726 2577
+3797 3534
+3954 3797
+4460 2708
+4477 4460
+4477 2708
+1434 3389
+1766 2706
+1767 2706
+3077 4671
+3077 1643
+727 4252
+4522 4408
+4522 4618
+4408 4618
+1899 1879
+1945 426
+294 2314
+2232 2314
+462 4455
+2148 4635
+2777 2148
+2777 4635
+3759 1320
+3759 3168
+378 3810
+3076 1360
+3076 3085
+2033 3923
+4727 3736
+4727 2556
+3899 4697
+4728 4697
+4728 3899
+4361 2502
+4361 3557
+2502 3557
+4155 3468
+1247 3407
+463 377
+4729 2944
+4729 2393
+2393 2944
+4691 4730
+2840 4730
+2840 4691
+2740 3811
+402 1
+3412 237
+2546 633
+2546 1771
+633 1771
+4627 4440
+4439 4627
+4546 1133
+2562 3172
+4666 3172
+4666 2562
+913 3806
+1742 1536
+3158 2633
+2937 2011
+1968 2011
+2739 1648
+1648 4272
+204 2339
+1779 4521
+1779 2074
+2074 4521
+4049 4046
+782 3517
+2209 4669
+3369 3551
+1782 3672
+1780 3672
+4109 1245
+4434 4109
+2343 883
+4403 3196
+1454 4672
+1248 2233
+3809 4631
+3809 1266
+4631 1266
+668 4246
+3049 4428
+3049 4427
+4289 3230
+983 4256
+2545 4256
+794 4041
+50 4041
+937 610
+110 953
+4654 4392
+4654 2169
+4392 2169
+1737 4440
+1736 4440
+2023 729
+1564 3632
+802 3632
+2382 2872
+2940 3016
+3456 4165
+3456 3962
+3208 654
+4731 2688
+4696 2688
+4696 4731
+4420 1276
+4420 816
+816 1276
+235 4012
+4630 3423
+3423 2931
+1259 4101
+882 1259
+4299 4308
+4301 4308
+4720 4000
+3998 4720
+2060 298
+299 2060
+2056 4226
+4226 1294
+2504 741
+3550 1112
+4154 4464
+31 1593
+4716 1771
+4732 2947
+4732 4430
+3794 1720
+267 1720
+969 4492
+3072 4113
+3072 2320
+3876 3879
+976 3890
+1963 4399
+4529 203
+4529 2152
+3717 3864
+3717 130
+2308 2216
+2308 4520
+3043 2134
+1545 4611
+3243 4009
+3244 4009
+195 1770
+195 3490
+1762 3929
+3751 4541
+3751 1990
+3792 4409
+2789 2048
+4638 4580
+4466 4580
+4733 3031
+4733 3030
+4707 4710
+1121 2178
+1120 2178
+4713 1313
+1867 4713
+4689 4674
+4689 3405
+3820 1777
+3830 2798
+4734 1902
+1901 4734
+1153 2521
+2898 4189
+4148 3416
+4148 1252
+1685 4302
+4471 2928
+2217 4276
+2217 4334
+4276 4334
+1557 3814
+3316 2419
+2419 3698
+1192 733
+1192 4578
+3475 4448
+2842 3667
+2844 3667
+2732 1938
+1224 4735
+4735 756
+4447 3617
+1424 1544
+4040 1424
+178 1814
+1998 1174
+3904 2408
+1514 2408
+1514 3904
+4736 4284
+4736 4737
+4737 4284
+567 4141
+1291 1385
+4523 3223
+1459 3223
+1459 4523
+1263 3177
+3177 3008
+3053 4600
+1516 2294
+2291 1117
+2291 1118
+264 1256
+2804 4363
+2806 4363
+4738 3092
+1800 4738
+4619 4425
+2754 4425
+4401 1
+2010 1964
+3798 833
+2627 3798
+4229 1189
+1188 4229
+4528 2238
+3105 956
+3105 2296
+529 293
+613 4640
+186 3696
+186 4105
+1298 3608
+1124 4409
+439 4204
+1904 4204
+2833 2246
+2244 2833
+1523 2986
+2986 1521
+4736 4535
+4736 4533
+2224 3975
+4651 1852
+3560 3611
+4684 3540
+3539 4684
+966 2285
+4537 4442
+4442 645
+3657 2180
+1764 4279
+4279 1765
+3941 4632
+4725 3805
+3805 4116
+3906 4709
+2165 4709
+4202 980
+4202 4631
+3637 2641
+2641 3703
+1441 4153
+1441 2145
+4463 1068
+369 2471
+3852 369
+4097 18
+2004 4097
+2087 3437
+3437 2836
+4384 4324
+4313 4399
+189 4219
+4594 189
+1591 769
+3766 1589
+3024 2783
+3871 1984
+3713 3344
+82 3472
+4607 1904
+1883 1904
+305 4739
+303 4739
+3805 499
+364 3805
+4364 3952
+4221 3952
+4221 4364
+3755 1391
+710 3321
+4685 4537
+3336 1719
+3336 4077
+3545 3307
+3835 3307
+3835 3545
+71 1277
+93 681
+1370 4740
+1368 4740
+4459 3844
+3801 3327
+1563 1886
+3154 1886
+4439 4329
+4155 805
+4155 3583
+623 2947
+4702 3065
+4582 3065
+1709 1576
+4587 1576
+620 3744
+2961 3657
+2961 3656
+1203 4487
+3922 4741
+4741 3218
+2112 4217
+4742 3044
+4742 1955
+1955 3044
+2900 3831
+3831 4025
+4494 150
+4494 148
+2323 3859
+181 4717
+181 4718
+3538 4122
+2021 4148
+4148 1282
+3241 908
+907 3942
+1663 3257
+2121 3623
+2011 2938
+156 4230
+577 1559
+795 509
+2005 3401
+2004 3401
+4626 4256
+2952 2297
+2297 2632
+3383 824
+3632 4532
+3778 3632
+4296 4435
+2884 3948
+3757 3948
+3195 3285
+3409 3285
+4743 3862
+4397 3862
+4397 4743
+3753 3058
+3160 3058
+3160 3753
+4612 2053
+4612 1820
+2909 656
+3313 469
+4588 4506
+3928 896
+4596 4235
+460 1457
+96 3827
+3827 3022
+1504 4335
+3086 4335
+2993 1217
+2993 2105
+1217 2105
+2017 4466
+348 2017
+4548 4659
+4462 4659
+3336 4287
+1159 3336
+3587 2926
+4366 2684
+4366 1240
+2148 2776
+1413 4744
+1415 4744
+3369 2193
+4468 84
+287 3331
+1460 319
+3911 2659
+4458 2659
+4458 3911
+2089 4000
+3596 2333
+2475 2573
+4119 2157
+3448 4119
+3652 4160
+2634 3621
+1444 865
+2037 1162
+1134 3064
+4046 3020
+4046 4558
+2562 3171
+4048 4745
+4047 4745
+241 968
+967 241
+3502 1062
+4367 1062
+3579 4502
+1478 3579
+1478 4502
+1662 3860
+3860 2450
+2113 3931
+2113 3784
+2443 4730
+256 2452
+3906 1043
+4526 3906
+4526 1043
+3866 2492
+4717 415
+4746 4717
+4746 415
+1695 4747
+1956 1695
+1956 4747
+2072 4739
+2071 4739
+4748 4133
+1870 4748
+3230 4249
+4289 4249
+2172 3816
+4263 1548
+4263 459
+1670 2860
+4447 140
+3986 140
+3780 1747
+2309 3780
+1071 2117
+1071 3285
+1158 1464
+4407 3685
+4407 3684
+4236 4004
+4236 4386
+2512 1076
+3568 4282
+3127 4321
+3295 4321
+1549 460
+3591 460
+995 604
+605 995
+2605 4385
+2605 4749
+4749 4385
+4443 276
+276 4441
+212 3895
+212 1379
+3895 1379
+4750 3484
+4750 878
+3967 366
+3777 229
+2945 61
+1975 3785
+1999 4727
+2555 4727
+3151 4306
+4184 4306
+500 4725
+500 3659
+4680 998
+4680 4728
+4728 998
+4469 1723
+2127 1723
+4751 632
+4721 632
+4721 4751
+4547 2288
+4547 1747
+3380 1605
+3380 846
+911 3511
+3220 4752
+3222 4752
+2012 3368
+2999 2012
+2999 3368
+844 826
+2635 489
+4525 4209
+4209 515
+2760 3942
+3306 3637
+4129 4344
+4250 4129
+4250 4344
+1581 1190
+4481 317
+4481 2904
+3520 1626
+4536 576
+539 4030
+2680 3485
+2680 3042
+3042 3485
+3376 1274
+2984 849
+2984 1320
+4740 2154
+782 4740
+4074 675
+4533 1700
+1699 4533
+912 153
+4301 3598
+4300 3598
+4605 270
+4605 1835
+1835 270
+2919 3555
+4753 3027
+4753 4248
+4754 2585
+4754 345
+3447 2510
+2589 3447
+2589 2510
+4111 4167
+3014 3628
+3886 1926
+1927 3886
+12 2668
+12 3726
+4015 650
+3657 3869
+3657 3581
+3581 3869
+937 4032
+2433 4609
+2433 4176
+3019 3263
+1920 3019
+1920 3263
+1862 4264
+3528 4264
+2618 4755
+4755 2619
+3664 108
+3884 108
+4241 4623
+2720 841
+2307 2521
+4157 4141
+1395 3170
+1202 1959
+1202 2251
+3615 1312
+1942 2597
+4280 2597
+4608 2786
+184 3495
+4259 184
+4259 3495
+3794 1721
+3988 1721
+142 1544
+1211 4646
+1211 4450
+4681 4326
+3014 4681
+4756 1375
+4756 4665
+4665 1375
+2230 1168
+3953 1168
+4423 4744
+4423 4701
+4701 4744
+767 3228
+3228 768
+3347 4433
+110 3005
+3958 1825
+3772 1825
+2483 1600
+2590 4679
+3926 4544
+3451 4544
+1078 807
+2124 446
+446 2122
+3397 841
+3397 1435
+800 4575
+443 3031
+443 4733
+4318 1966
+2859 994
+2337 2755
+631 2546
+3602 631
+3602 2546
+902 2385
+200 2518
+1699 4534
+4241 3314
+2127 1972
+1148 1972
+3051 890
+457 3051
+457 890
+4244 2364
+350 4244
+4027 2265
+457 4067
+455 4067
+4050 730
+4050 755
+2148 4199
+3108 4694
+2265 3108
+4673 3423
+4673 3422
+4644 1491
+216 4757
+216 4758
+4758 4757
+4019 4703
+563 4086
+3955 4095
+1649 374
+728 4005
+2572 3679
+4128 4706
+4625 2334
+4625 1359
+1782 3673
+2882 3673
+4667 2235
+4759 609
+694 4759
+4322 699
+4322 698
+429 2417
+429 2467
+2467 2417
+4744 2418
+4760 2418
+4760 4744
+704 3393
+3393 703
+2228 596
+3209 1621
+1558 1521
+1557 1521
+4742 1953
+4742 2264
+4754 3079
+4754 1620
+687 395
+686 395
+1466 1846
+4657 127
+1676 4761
+546 1676
+546 4761
+1796 1589
+4704 2970
+4735 301
+4512 4404
+3075 1360
+3127 3931
+3662 4762
+4762 3094
+4529 1586
+4391 3152
+4451 1419
+3446 3997
+4763 1656
+3749 4763
+2158 2873
+132 2873
+132 2158
+736 3043
+914 2209
+3947 4688
+4087 4764
+4764 4247
+2962 3365
+1297 4751
+4404 4751
+4742 1309
+4765 236
+4765 2512
+3306 4415
+3306 1076
+4415 1076
+2608 2942
+4590 3429
+4603 3506
+1258 3506
+2358 4667
+3907 2055
+2352 2055
+2352 3907
+3132 4495
+3385 3470
+1961 3385
+2998 1364
+1892 2787
+4717 183
+3635 2305
+2980 2305
+2016 4466
+1082 1132
+3998 4654
+1490 4740
+3517 1490
+3517 4740
+4278 1196
+4278 642
+1196 642
+1078 3096
+1730 3797
+1316 2532
+809 4640
+165 1385
+4110 221
+221 2560
+2428 4719
+331 4719
+1084 4044
+1084 4642
+4044 4642
+3396 2609
+3617 3551
+3552 3617
+4766 670
+4766 669
+4357 4752
+4752 4312
+3519 3799
+4468 3449
+4091 3449
+2161 3036
+1850 2426
+1875 4609
+888 3042
+4148 4767
+4767 3416
+4209 513
+4665 1150
+3311 1150
+3114 1615
+4267 1799
+908 3240
+3240 1358
+875 4370
+876 4370
+1514 3532
+3874 134
+4716 2298
+379 2698
+2589 4679
+1157 428
+1157 734
+428 734
+2278 3057
+4553 3057
+4296 4446
+2503 4296
+4634 4376
+4677 3479
+4677 1561
+3277 2814
+4609 4540
+4513 211
+1401 398
+4193 2858
+1528 4673
+3547 871
+3547 870
+4701 2418
+4701 2912
+4063 3481
+1461 2183
+1461 2184
+4677 4219
+3917 2013
+3674 3212
+4594 516
+4674 804
+1650 2968
+4567 1650
+4567 2968
+2393 4360
+2944 4360
+2521 4473
+2904 2857
+772 2714
+772 2716
+653 2389
+4372 1014
+1013 4372
+4304 4131
+4756 4653
+4150 4653
+4150 4756
+3160 2633
+4768 589
+4117 4768
+4117 589
+4293 2176
+4565 2176
+4565 4293
+206 3677
+2757 2557
+2555 2757
+4322 2118
+2983 2118
+2983 4322
+855 2356
+2071 855
+2071 2356
+3304 2452
+4092 2310
+4092 3779
+3779 2310
+1601 2763
+3812 153
+3958 128
+129 3958
+353 323
+353 322
+1209 4056
+3625 400
+2854 3781
+1482 1522
+2500 1522
+3908 4769
+4769 1293
+2871 2910
+2924 2910
+3561 2099
+718 3013
+1971 1724
+2138 2761
+4391 3151
+4595 2369
+4595 2368
+238 3178
+1091 3178
+1091 238
+431 2648
+4231 2082
+1272 1045
+2246 1272
+2267 4027
+3170 1042
+725 3654
+133 4122
+3192 4122
+1856 1107
+1856 1106
+3191 3157
+3860 874
+894 1732
+4770 4155
+4770 3583
+1703 382
+749 1145
+4203 966
+964 4203
+2031 3413
+2792 4498
+4347 4011
+4011 4355
+2673 1407
+2673 1406
+3247 659
+3453 1942
+4604 2531
+3263 1919
+821 1675
+3500 3584
+2655 3584
+639 1527
+3329 3286
+3329 4616
+152 3108
+152 1642
+4539 3981
+4684 3981
+2552 3528
+2370 965
+3780 2310
+2340 3005
+2340 4085
+3376 3873
+2067 311
+310 2067
+926 1785
+4749 538
+4749 539
+1774 389
+3285 3194
+1071 3194
+3272 3243
+3272 4009
+4763 2388
+4763 766
+2388 766
+1112 3863
+3550 3863
+2430 3395
+2834 589
+2580 3321
+2570 1743
+3532 1107
+4673 3348
+1992 4171
+2753 4649
+2752 4649
+4760 4014
+1413 4760
+764 3020
+4049 3020
+4566 1651
+1651 3448
+3703 2453
+4771 4564
+4022 4564
+4022 4771
+169 252
+4068 252
+4068 169
+1903 3776
+120 3863
+3105 4330
+3105 955
+4098 4752
+4486 4098
+4486 4752
+4307 1904
+860 349
+3216 3623
+946 4152
+946 4079
+3965 4445
+3997 3965
+3966 3097
+3966 3098
+2245 3523
+2350 2824
+2798 2617
+4641 2617
+4641 2798
+3234 871
+1861 1879
+601 2915
+1205 2915
+2263 4470
+4094 4012
+235 4094
+767 605
+1162 4532
+4482 4532
+4482 1162
+4388 4538
+2434 2558
+2060 2392
+1341 400
+1341 3559
+3809 2815
+1776 3575
+1394 3575
+4772 4144
+4772 869
+1005 4187
+2420 4547
+3925 2420
+3925 4547
+3830 3032
+103 4678
+105 4678
+174 2966
+3146 274
+242 968
+4390 800
+4390 3774
+1947 426
+4073 1947
+261 700
+1829 2537
+4461 3009
+2880 3009
+3803 2771
+2954 3436
+4265 3436
+1697 2728
+4475 1697
+175 4605
+4605 176
+3681 3344
+2620 849
+1801 4738
+424 1381
+3968 4139
+3187 4521
+118 4292
+118 4291
+3322 2508
+4679 2508
+382 3309
+2599 2736
+1058 68
+3393 1261
+1262 3393
+4416 4768
+3993 1280
+1280 4454
+4486 3222
+3394 3124
+1155 734
+3790 3935
+3742 4590
+2330 4476
+1767 1977
+1767 2982
+1977 2982
+1784 3808
+1784 4076
+213 1635
+1877 2897
+4540 1877
+4303 4517
+3120 4517
+1992 3710
+1992 4211
+1597 4338
+1597 4653
+4760 3315
+4499 172
+4499 2002
+2250 2013
+3744 4284
+4736 3744
+2916 4702
+665 4702
+4527 237
+4527 4094
+237 4094
+3626 102
+3626 101
+2359 1742
+2852 4266
+4690 2850
+4773 3806
+4773 3811
+3806 3811
+4560 1693
+4560 1692
+3823 762
+192 4675
+3680 2080
+2080 1546
+476 2239
+1993 2746
+4771 2746
+4771 1993
+4654 4632
+3853 111
+109 3853
+3776 3960
+4774 904
+4774 903
+3885 479
+2354 3907
+3079 347
+345 3079
+1170 3598
+3984 2800
+4608 1853
+3530 4739
+2643 2532
+4550 3838
+3838 3920
+3376 4147
+1600 399
+3693 2411
+807 1229
+807 5
+4254 4484
+4330 4190
+3104 4330
+2595 2362
+2595 3842
+4564 4764
+4771 4764
+3988 3399
+3399 4078
+2050 4483
+2050 1603
+4483 1603
+4016 3957
+1708 1576
+2380 4573
+3665 4573
+3665 2380
+3057 410
+3202 4693
+3300 4693
+1402 3480
+1402 4655
+3480 4655
+2497 1726
+3974 2224
+4151 2224
+4151 3974
+3206 611
+4775 2638
+4743 2638
+4743 4775
+3776 3213
+3776 3143
+3213 3143
+3002 3987
+3002 3733
+1218 2163
+3903 4364
+4365 3903
+2545 4626
+4195 1802
+2735 3664
+817 3026
+3303 1484
+1483 3303
+3437 2837
+435 2848
+2582 1954
+4583 2971
+4583 984
+351 3890
+351 976
+1480 521
+3802 4014
+3965 4029
+1183 463
+1183 377
+3591 1457
+4704 4156
+4496 362
+2129 3608
+1523 4592
+4592 1522
+3509 1203
+3509 4487
+4650 4467
+4650 2211
+2211 4467
+1053 3874
+3892 3874
+3892 1053
+3022 974
+3022 3144
+323 1349
+3067 2802
+70 2802
+70 3067
+2172 2703
+2703 3150
+3473 2280
+3035 4453
+3749 4541
+4763 4541
+2862 2871
+441 4733
+441 4419
+4733 4419
+1836 3748
+297 4683
+3185 297
+3185 4683
+1159 4664
+3336 4664
+5 806
+4 806
+1757 533
+3911 411
+1941 3867
+923 3867
+4617 4408
+4617 4425
+14 342
+2081 4611
+4613 3804
+3697 4613
+1887 780
+1887 937
+3146 4354
+3684 719
+3991 4718
+3991 2710
+2710 4718
+1568 2350
+2538 4428
+4099 4428
+4612 1822
+4276 4734
+4276 1304
+1304 4734
+4328 4558
+4351 4558
+1300 3181
+4748 4328
+4748 4558
+3032 3986
+2837 3435
+1126 4120
+4134 4120
+1128 2376
+3901 3519
+4196 1062
+4196 1064
+4300 40
+4300 41
+3603 158
+3963 3603
+631 1431
+1687 3407
+1685 3407
+3570 4671
+135 581
+135 4682
+472 4501
+4070 872
+3090 2606
+1163 1564
+1163 1566
+3232 1383
+1193 3262
+3418 3020
+651 3020
+1443 1010
+1443 2054
+4176 4404
+4176 4661
+3267 4772
+3717 4772
+4737 714
+2802 4737
+1001 3719
+1581 3774
+4136 629
+852 43
+3419 181
+2636 4715
+3655 629
+934 622
+4213 622
+4072 2617
+4121 2617
+2787 1250
+3903 3952
+3905 4526
+3905 3338
+3274 2627
+4443 737
+3253 3870
+4218 2675
+4217 2675
+2660 2986
+2986 4626
+4776 1057
+4776 2229
+4205 4743
+4205 3862
+3125 702
+3125 703
+764 2388
+764 2389
+2086 2994
+1220 1253
+4777 2488
+4777 263
+1769 4206
+4003 4206
+784 490
+3263 3275
+1280 549
+4572 1280
+159 4037
+1265 4599
+3168 2362
+4048 1367
+1367 4745
+4610 4683
+4610 3946
+3946 4683
+1715 3072
+3072 661
+2727 2714
+2996 4355
+1810 4355
+1810 2996
+4778 2730
+4778 398
+4753 2639
+4753 1568
+1735 4408
+4408 3199
+3599 3546
+3599 3545
+3773 537
+1743 36
+3994 2699
+2588 1075
+907 2853
+2853 906
+668 4247
+4316 3213
+3965 4149
+199 553
+3472 831
+3472 830
+1516 2295
+4050 3629
+730 3629
+524 879
+2075 2887
+2757 2000
+4385 538
+3748 1072
+1837 3748
+1837 1072
+4003 196
+4003 256
+3730 1946
+494 329
+115 1499
+3125 2441
+368 4745
+3799 3274
+1425 4369
+1425 4490
+4369 4490
+218 3113
+4500 4508
+3051 2879
+31 2860
+4715 2273
+2636 2273
+523 3219
+3872 4212
+3872 3754
+3366 1128
+176 1835
+3506 4101
+3506 1259
+4767 3946
+1284 3946
+1284 4767
+4250 3169
+3169 4249
+2649 854
+4645 854
+2649 4645
+698 1406
+1007 1919
+3925 1747
+3887 1984
+3887 1983
+3839 2077
+3839 2078
+2015 2027
+2015 1717
+2027 1717
+2781 3820
+3919 2781
+2337 4508
+1592 2972
+586 2151
+4779 2151
+4779 586
+3418 764
+1124 981
+3792 981
+3792 1124
+2290 1117
+3271 4750
+3271 4741
+4750 4741
+4278 3654
+3633 3318
+359 2463
+359 2464
+842 2151
+1374 2480
+2614 2958
+1982 2744
+3542 4568
+4568 4055
+4381 436
+1492 813
+112 535
+4660 535
+1481 4686
+2553 3785
+1975 2553
+4320 4348
+821 4320
+821 4348
+3703 2207
+3703 3047
+4527 3412
+3782 2751
+3633 2751
+3772 1823
+1487 719
+2686 1992
+1623 2914
+2913 1623
+1161 4780
+1163 4780
+2820 3757
+3471 1064
+4416 1064
+4416 3471
+4781 297
+4781 1384
+3464 1112
+3464 3863
+3846 4514
+3846 1190
+4329 4061
+2936 112
+2139 2966
+3759 2793
+1858 4041
+116 1500
+4126 1990
+3751 4126
+501 3893
+3995 2604
+4200 4349
+4349 2865
+2930 3964
+3161 3964
+3164 3309
+4638 1356
+3927 4685
+3927 4684
+2541 2677
+2250 4024
+2880 3673
+2666 4492
+4452 2058
+2956 3436
+1224 360
+1988 766
+1988 765
+2349 4206
+4711 3918
+2078 4711
+2289 2141
+2289 3174
+3876 4782
+4782 3661
+2101 2274
+598 2274
+598 2101
+2080 1545
+3391 1171
+3123 3394
+1974 3847
+2870 2845
+2737 2845
+3852 2997
+1527 2353
+4614 4752
+187 700
+891 187
+4622 3155
+4622 4233
+4233 3155
+297 3554
+3475 3017
+688 3318
+4769 1294
+1113 3463
+1112 3463
+4452 3103
+1267 4452
+2738 959
+2049 1031
+1031 859
+1560 3636
+2782 3820
+3077 1641
+2326 4221
+4783 4425
+4617 4783
+2884 1364
+3043 3148
+4622 4710
+1551 1821
+1821 1550
+2573 2643
+1441 3667
+1762 4784
+1760 4784
+3987 1811
+820 545
+2258 4405
+3647 2258
+3647 4405
+4023 706
+4022 706
+3025 1565
+2875 3319
+2273 3492
+4549 2273
+4549 3492
+3852 1660
+3035 2665
+938 4311
+938 1852
+13 4546
+4644 1712
+1491 1712
+500 3805
+2329 4723
+1688 1329
+3585 3939
+4154 4544
+4154 3691
+2781 2542
+144 1544
+144 1424
+3966 3997
+3485 4238
+3259 1539
+1309 3044
+4398 3831
+1379 1705
+4393 2989
+2199 2656
+683 1139
+346 2832
+753 4719
+3010 4335
+4645 3010
+2309 4520
+1311 2258
+1323 3031
+3715 1176
+3715 3071
+3426 4394
+1804 4199
+4770 394
+4770 3468
+3271 2039
+4006 4105
+4698 4105
+1229 2981
+721 2981
+4554 3130
+70 2803
+4676 675
+4676 4074
+1817 139
+3625 4573
+4253 2400
+4779 2498
+4779 3225
+4162 138
+4162 2992
+2112 2675
+1241 318
+2847 731
+58 2852
+708 2852
+3505 1145
+4776 3460
+4776 4102
+4726 3629
+4726 3630
+3120 1018
+1676 545
+1946 1871
+1377 2046
+1377 391
+4181 964
+577 3814
+2631 4200
+2985 3147
+4535 714
+4736 714
+216 4290
+2252 1848
+3969 366
+875 3969
+2131 1364
+2131 1177
+3122 1018
+4259 3804
+184 3804
+664 3730
+673 3671
+231 4635
+1207 4235
+4686 1207
+4686 4235
+3382 4337
+31 2068
+1593 2068
+4678 1303
+105 1303
+2969 3024
+2080 3938
+4244 2015
+4244 2017
+2062 2392
+4378 512
+4378 511
+4305 3026
+25 4305
+3407 4302
+1460 4487
+1302 3335
+4451 1498
+3669 3183
+3183 4610
+4729 4054
+2780 4729
+2780 4054
+4691 1664
+4691 921
+3953 1750
+1829 1338
+1829 1337
+750 327
+2335 1798
+882 611
+1971 2829
+4067 1644
+1644 3847
+3947 3757
+966 3257
+2468 2068
+2317 4353
+3588 3603
+1378 1705
+4127 1988
+2296 2337
+3991 3419
+3419 1518
+527 650
+3315 650
+3851 369
+625 1384
+3172 4315
+3447 788
+4501 2852
+83 2852
+3590 4756
+4756 3589
+3599 2178
+3513 4622
+3513 4233
+1962 4302
+3552 4447
+1669 2458
+4172 2818
+4329 2400
+4056 259
+259 1812
+1126 3841
+3887 385
+1195 2274
+3976 4144
+3268 4144
+3346 1973
+1405 2982
+4322 2982
+3070 3115
+4785 3317
+4785 355
+1743 3325
+4786 1743
+4786 3325
+581 3223
+321 3223
+1653 4624
+2889 4624
+1680 2277
+315 1321
+3758 315
+4666 1217
+3894 4762
+4762 2319
+630 4623
+630 4432
+4399 4502
+1476 4502
+1203 4573
+4177 1431
+1713 4177
+2803 2410
+2100 3635
+4358 2935
+4197 2935
+4197 4358
+2063 576
+4390 4575
+4064 2569
+1105 4052
+1107 4052
+4177 4661
+3267 4144
+1958 3924
+3415 2429
+2414 1716
+2414 1717
+4500 636
+4655 3482
+2028 3709
+2028 4723
+3709 4723
+1844 1912
+1713 2431
+4712 3405
+4712 803
+2414 4723
+4078 4584
+3384 4078
+1849 3194
+1750 1168
+3456 4523
+66 1326
+4607 1052
+1439 1052
+4758 3113
+4758 3112
+1890 124
+3845 2079
+3791 1488
+1488 3685
+4366 334
+4779 3287
+4779 2095
+2095 3287
+2343 885
+299 3184
+297 3184
+1195 3922
+2839 3777
+2102 2274
+3504 1352
+4696 2923
+4731 2923
+2446 4739
+4762 2318
+142 3243
+4787 4697
+4524 4787
+1430 631
+678 3441
+2439 676
+2439 4606
+4606 676
+1175 517
+2689 517
+2899 932
+2089 4662
+4000 4662
+4712 2830
+2830 3405
+2615 4641
+2267 1642
+4761 1675
+4761 4120
+2222 2455
+4630 3349
+1320 2805
+3226 2805
+3989 4700
+3989 1721
+731 4223
+4208 4223
+4208 731
+4471 2998
+2075 3134
+3236 3441
+3236 2038
+3518 2960
+4729 3729
+3728 4729
+1741 3110
+1741 4574
+4574 3110
+1313 2258
+4314 1432
+4461 3008
+1854 3440
+2248 3440
+4073 3731
+2584 4349
+4638 1695
+3834 3725
+2692 1092
+697 549
+4560 2702
+3582 3001
+688 4207
+1486 4100
+3754 635
+1733 3800
+2530 318
+1241 2530
+4290 4238
+216 4238
+2289 1665
+1163 1024
+1024 4780
+4250 1167
+1812 260
+1813 260
+2980 2304
+1002 1243
+58 4755
+554 58
+554 4755
+2177 338
+2612 2830
+1490 2196
+4141 566
+4765 1779
+3102 4765
+1850 2009
+3247 876
+3475 2204
+3475 2271
+1391 1326
+2803 898
+231 2149
+3588 2149
+4702 4073
+665 4073
+3356 1066
+1248 3175
+1247 3175
+2666 3932
+1152 4778
+1971 3145
+3145 2829
+3573 1041
+532 3335
+4294 3335
+4294 532
+3971 2612
+3971 2830
+686 4207
+2435 1272
+936 622
+621 936
+1539 4493
+1407 4571
+4572 1407
+4401 4407
+2919 3344
+2589 2508
+1802 4062
+1802 4061
+2150 1805
+3913 4061
+4680 3899
+107 3664
+1166 4295
+174 2139
+2993 2086
+3118 3138
+3312 1122
+3312 3983
+2547 1771
+2547 3109
+1771 3109
+1616 1456
+662 2346
+2346 1798
+3442 207
+4178 3298
+4636 3298
+4636 4178
+3767 3132
+4639 3635
+4639 2979
+230 2493
+2493 229
+351 4319
+2111 1846
+3066 1846
+1958 3768
+1272 1046
+4746 4699
+4746 29
+2996 1808
+4770 687
+206 3678
+206 2231
+4708 3197
+2877 4708
+149 2364
+4021 4554
+2886 4554
+4258 3769
+4028 1398
+1295 3204
+4614 4045
+4614 4312
+4113 2339
+772 4551
+2063 575
+2063 847
+1025 4090
+4047 3851
+1805 4199
+2150 4199
+4598 792
+4762 3059
+3894 3059
+4732 3495
+958 3844
+4229 1611
+3872 1715
+4225 4613
+4465 3691
+4154 4465
+2976 1922
+855 1583
+1025 4780
+4607 4204
+586 2498
+1927 3760
+2115 1927
+1263 3178
+3902 3178
+600 2915
+4639 3265
+4175 4639
+4175 3265
+2159 2281
+4764 2746
+4589 4505
+4589 3439
+4505 3439
+2393 3729
+4276 3137
+3015 859
+4689 804
+3226 2804
+333 2496
+2496 1261
+2940 3467
+1167 4129
+4569 2723
+4482 2037
+4774 4045
+4774 4614
+3774 1190
+2664 999
+210 327
+1615 4730
+2210 411
+423 2420
+86 1724
+86 1971
+3497 4378
+4486 1212
+4699 415
+4757 3113
+738 746
+193 4675
+4280 3527
+4507 4663
+4507 1471
+1267 1136
+1267 2058
+4270 1052
+4270 1439
+4326 580
+1173 4326
+4349 3421
+345 3421
+2992 2458
+4083 2617
+209 1926
+3836 2600
+2110 3638
+3284 1710
+1710 3859
+2532 1847
+4720 4788
+2276 4788
+2300 2359
+3094 2318
+485 4237
+485 2927
+2713 2440
+3510 4694
+4268 2100
+4268 3635
+4789 3838
+4550 4789
+471 1009
+3474 1411
+1047 3523
+1047 3704
+3744 1700
+2445 4277
+4277 3115
+3277 2816
+2179 1688
+3767 4495
+4008 2835
+4568 2114
+685 1044
+3854 2606
+4475 3885
+1498 2710
+4459 4020
+4019 4459
+1900 127
+2593 2495
+2495 704
+4030 4224
+3755 4705
+1389 1113
+3927 4441
+276 3927
+2820 3462
+3462 1707
+4722 4197
+4722 2001
+546 4201
+4308 168
+1033 1787
+4288 3695
+1084 4562
+1866 4405
+3309 3163
+4101 3909
+3507 4101
+852 3544
+4747 1897
+4747 1895
+4707 1563
+4707 3155
+3971 4712
+4115 4789
+3440 282
+881 1259
+3889 4166
+4429 4659
+3006 3100
+299 3100
+638 2353
+1041 234
+1303 1902
+1304 1902
+4658 2786
+4608 4658
+1392 1053
+1987 744
+744 3618
+3358 2741
+1603 2036
+3197 137
+4321 4348
+3856 1623
+1095 1813
+1277 815
+816 1277
+4605 3787
+3916 2013
+1802 1226
+354 3632
+314 3632
+103 3142
+103 520
+4062 1226
+1319 859
+3252 2221
+2547 1473
+3626 2763
+1810 4011
+3109 4309
+3371 1821
+4591 3190
+3579 3869
+2224 1008
+1123 3138
+3636 3709
+3708 3636
+634 3072
+3956 2826
+4673 3557
+1138 1049
+2562 1217
+4720 2219
+3420 2219
+351 322
+4053 2362
+4239 3314
+4143 2185
+4143 2243
+3118 2604
+4641 4395
+4396 4641
+4530 3197
+1562 3636
+1181 2845
+2737 1181
+4250 1056
+1056 4344
+3680 3938
+3010 600
+22 573
+3169 1171
+1171 4249
+58 2851
+4755 2851
+4681 580
+2465 1118
+2303 1118
+4657 1132
+2517 4126
+3979 4126
+2165 4089
+2007 2775
+2205 3703
+3620 3319
+2899 2372
+159 3603
+3193 3293
+4310 524
+3956 4380
+4421 4656
+4421 4706
+4656 4706
+204 2321
+310 3857
+4656 357
+36 3325
+3323 36
+1104 4722
+3168 2793
+1980 3258
+2334 3790
+3388 2122
+3283 2860
+2561 4715
+4715 2396
+2923 1269
+4731 1269
+3037 4160
+4228 2600
+4485 2242
+3989 2421
+2421 4700
+4163 2055
+4489 980
+1893 4078
+4193 1141
+2669 1824
+128 1824
+1234 3806
+1205 1793
+2295 2723
+4569 2295
+2611 4498
+2613 4498
+3129 3931
+878 3218
+156 4551
+4746 4714
+1209 4450
+216 3113
+4557 3019
+1870 4557
+1870 3019
+625 2392
+4430 2392
+4136 1878
+736 3148
+295 3148
+3981 4538
+6 2344
+96 4713
+4713 3827
+1646 3847
+4242 790
+4598 4242
+4598 790
+4652 3527
+1934 1308
+4732 4259
+2951 3403
+1312 571
+4183 4364
+4690 3673
+4690 2880
+4203 470
+2943 4360
+160 4481
+3906 685
+4172 4339
+3910 1547
+914 4669
+2770 3803
+3786 568
+3095 1310
+4010 3600
+4010 3483
+4706 357
+902 3343
+4080 3864
+1941 1511
+4777 959
+4777 2738
+4092 3876
+4514 2818
+1786 3982
+4778 2731
+1152 2731
+1348 4252
+2003 2257
+957 1942
+3238 3389
+1206 3389
+2457 3028
+4567 3788
+3788 557
+128 1825
+3928 2709
+1738 4194
+3075 1641
+3419 4718
+343 968
+343 4332
+4455 4426
+3994 4455
+185 2946
+4693 3299
+4560 4634
+4100 641
+4215 2735
+889 187
+3857 4308
+4475 4531
+3419 1216
+4169 3012
+2214 2971
+3235 4266
+3000 4295
+1166 3000
+4583 1995
+4593 4583
+4593 1995
+4275 1032
+4275 1033
+52 3293
+3883 3738
+789 627
+2787 2070
+2789 2070
+4084 106
+68 4084
+68 106
+2086 2105
+2085 2105
+4299 3857
+887 1681
+1575 3831
+3205 853
+885 4123
+388 4618
+4773 2740
+759 1207
+758 1207
+4507 4664
+4327 179
+454 1059
+4056 3139
+3140 4056
+677 3441
+2604 3138
+4631 2815
+3861 2450
+4457 4759
+2955 2198
+4251 1290
+1797 1290
+3605 2273
+1841 3088
+4688 3949
+4463 4688
+4463 3949
+1935 1674
+4588 900
+1141 2731
+2228 2731
+2280 3646
+2784 998
+2784 999
+310 291
+4301 168
+2021 168
+2021 4301
+3614 3326
+3614 3335
+1822 4783
+1821 4783
+1001 1243
+2913 3652
+849 929
+4606 849
+4658 4579
+1128 2378
+3561 2136
+1667 3972
+3697 1921
+4358 2576
+3639 2576
+3054 4415
+4094 329
+2804 3227
+3834 4055
+2046 4412
+2464 360
+528 245
+2480 1329
+1063 3354
+1063 1226
+1540 2189
+1016 1540
+664 1946
+4138 2470
+4657 1131
+2229 108
+821 3879
+2423 2428
+4389 2423
+608 3258
+608 4759
+4759 3258
+2348 2019
+4670 718
+2251 4670
+2799 2491
+2745 1917
+2745 4785
+1917 4785
+1078 3424
+4708 2152
+4577 1337
+4092 4782
+4093 4782
+4484 2443
+3589 3445
+3589 595
+1181 83
+1455 2707
+2343 2523
+4499 2613
+82 831
+1541 2189
+4585 848
+4212 1352
+3922 2039
+597 3922
+4173 1710
+4173 4587
+2218 4334
+3046 4749
+221 2567
+2239 1717
+2898 817
+1478 3580
+2211 4368
+4393 3545
+253 4426
+1569 3028
+1568 3028
+70 898
+369 4745
+3851 4745
+3723 4748
+262 452
+2213 3257
+4041 2362
+315 3970
+831 2798
+4769 2055
+4758 4238
+4453 2665
+4143 3976
+4784 3897
+3357 4784
+199 59
+320 3223
+3136 3216
+1739 162
+4741 878
+3744 4533
+52 4668
+3293 4668
+4780 4090
+223 4577
+224 4577
+2140 2761
+4768 2834
+3018 2270
+250 2221
+3188 2381
+1173 4670
+1202 4670
+2200 1310
+3095 2200
+89 4788
+89 4414
+4788 4414
+3010 3086
+2637 4242
+4609 1877
+4215 1593
+591 2448
+1216 1518
+1570 3700
+3581 2180
+3496 2180
+3496 3581
+4373 1299
+4327 1443
+4338 1005
+2012 3743
+4522 2169
+4654 4522
+22 4096
+24 4096
+1596 570
+1919 3262
+846 4585
+1354 1253
+1254 1354
+1741 1473
+1829 2496
+4636 3296
+1616 1160
+753 340
+340 752
+3453 185
+3906 1044
+3905 4001
+3976 2185
+3291 2185
+3783 765
+987 1255
+4083 1255
+3649 2257
+162 4480
+2004 3133
+4524 514
+1973 2554
+1067 3055
+2694 300
+2379 300
+585 2268
+3112 4238
+2460 2992
+1269 2688
+2345 1467
+969 2666
+1935 1673
+4699 416
+3707 1408
+397 1600
+350 2017
+4423 3566
+1153 4473
+3378 2048
+3167 2112
+2297 4561
+957 4628
+3002 3582
+2203 3632
+1535 3632
+1535 2203
+1239 2221
+2518 198
+4497 379
+4604 2533
+1278 2698
+2311 4246
+3961 3634
+2920 465
+230 2494
+4153 3667
+4008 3374
+3264 4590
+4525 4787
+156 2726
+1009 4672
+4444 4672
+4444 1009
+2744 1447
+4510 3379
+3269 2516
+3389 1207
+3756 4705
+4484 4277
+4485 4277
+3798 1626
+704 1261
+2495 1261
+4040 4369
+4040 1425
+4456 1821
+3634 1824
+2669 3634
+4504 3920
+4632 4522
+4352 1654
+1654 1429
+2079 2774
+3201 2774
+3101 1281
+3666 1281
+3902 3964
+3094 3881
+3109 716
+3253 1342
+3024 3955
+2343 4123
+1418 4651
+4437 1294
+1906 4576
+368 145
+4288 2493
+4299 40
+1426 4253
+1414 2010
+1241 1511
+555 2725
+3069 2802
+3069 4737
+3519 4570
+2581 3307
+4175 3428
+3428 4639
+1865 821
+1865 822
+4375 2143
+4375 1693
+4345 4033
+4638 4747
+4504 3438
+1455 4086
+97 1547
+1764 3580
+4741 2039
+212 327
+1407 1766
+3221 3646
+1515 3711
+3644 4479
+3644 4478
+1595 4653
+4707 4622
+3586 3603
+314 3970
+2365 3499
+4556 998
+3977 467
+4690 3009
+3146 3173
+1318 4343
+4599 4660
+4585 3381
+3380 4585
+4083 4121
+4031 1048
+2131 4245
+1844 3066
+2101 599
+675 4637
+4507 3336
+1016 1594
+1292 164
+4685 4441
+4685 4442
+4629 3636
+4629 3709
+1648 3474
+4372 1648
+4372 3474
+4692 2527
+3799 2627
+2351 4206
+244 4260
+3702 4700
+2449 1417
+630 4624
+2643 3764
+2643 1847
+3713 3342
+3899 4787
+1889 1538
+1145 2501
+4042 4705
+4705 3950
+3824 2626
+537 4030
+2965 3443
+4669 4402
+2573 3764
+4422 1019
+2355 1005
+3785 2375
+1723 4786
+4469 4786
+982 3793
+3793 981
+1414 1970
+118 594
+1690 3414
+4243 4766
+4766 1690
+3431 218
+217 3431
+1648 1411
+2738 1244
+180 2072
+4174 4245
+1041 4518
+4518 234
+1161 4090
+2669 3961
+554 2619
+3136 3674
+4633 3951
+4633 4042
+2499 2268
+4519 2824
+1956 1895
+2500 1521
+1827 3743
+4576 560
+2464 3188
+1001 4790
+2904 4790
+4771 2018
+4022 2018
+1200 4000
+2499 249
+3357 1760
+1760 2960
+1396 273
+2518 273
+2346 3808
+4724 3204
+4724 3203
+4781 3554
+3179 238
+4774 4615
+3216 3571
+956 4561
+2577 3629
+3271 4009
+3588 485
+1592 4699
+3286 3270
+2713 850
+2961 3869
+1975 2554
+3703 2454
+4440 1803
+86 3145
+742 2728
+2503 2728
+4686 4596
+4477 972
+972 4460
+4776 3461
+3837 4789
+3044 3983
+3717 4080
+4772 4080
+874 3862
+4174 3948
+2167 1594
+4026 39
+4678 3142
+4243 2950
+3155 4234
+4517 2459
+2636 3492
+2983 936
+1978 936
+4777 1244
+2444 1615
+2444 4730
+2693 4735
+1224 2693
+4732 2062
+3641 530
+2962 2378
+4518 3245
+4767 1282
+96 1867
+524 4253
+4625 1360
+1942 185
+1052 1775
+4237 487
+3617 3369
+4358 2184
+2890 1429
+1980 608
+4722 1434
+4180 465
+2676 3545
+3052 354
+4031 4208
+4683 3945
+1606 1108
+3185 4610
+4388 2237
+4387 2237
+4714 2710
+3216 2670
+1523 488
+2070 2048
+4496 24
+3719 4790
+1100 4790
+3840 3107
+950 2775
+2009 2426
+3454 4419
+2720 2208
+2283 4490
+2213 966
+966 470
+1313 4405
+1207 1922
+238 1090
+2390 3896
+4430 2062
+4424 3566
+1998 1175
+4766 3414
+2080 4611
+3471 3386
+3471 2834
+4586 1728
+1598 2901
+2988 3688
+1051 3688
+2183 3736
+2183 4727
+2093 2163
+664 1871
+3540 3981
+3844 4703
+4019 3844
+4505 4588
+4615 3713
+4479 972
+4606 2712
+3933 755
+371 4552
+3084 3568
+1900 4657
+3807 1757
+4275 4048
+4785 1916
+4075 1775
+3628 4682
+3628 4681
+154 2957
+2149 4635
+2118 936
+3513 1037
+1792 1299
+3822 3205
+4222 279
+3904 4365
+2898 818
+405 1020
+2184 2576
+673 4637
+573 4096
+2572 4096
+771 2957
+1578 4069
+2844 3934
+2503 2602
+4120 4488
+632 3893
+4434 4436
+3197 1789
+1535 354
+198 273
+4509 1615
+1757 4773
+3807 4773
+2602 2728
+4043 211
+262 4777
+2408 3510
+4491 2283
+4602 1095
+1056 2485
+3463 4687
+3409 3284
+3966 3589
+1889 2360
+4361 3556
+1979 4651
+1295 4724
+987 1256
+2985 2619
+1168 4129
+3783 4320
+2056 1090
+4182 3248
+4207 3248
+3519 309
+2287 3519
+4444 1008
+4331 3401
+3883 2457
+4667 269
+3212 4334
+2180 1500
+4619 4783
+2217 4734
+3518 1760
+4179 4386
+2769 2429
+4279 3496
+2105 2525
+2104 2525
+2686 1991
+476 2856
+4586 1010
+2445 4484
+3172 1042
+309 4570
+3312 3537
+4336 1516
+4589 3438
+1233 1576
+4456 3371
+4456 3370
+831 4395
+4395 1036
+170 3204
+179 1443
+1085 4044
+4485 3746
+4277 3746
+4615 3342
+4043 3569
+485 2149
+1821 4617
+2312 3349
+1559 3814
+3650 4419
+3265 2979
+302 2379
+2816 4201
+3277 4201
+1938 2640
+2768 241
+3907 4769
+4415 2512
+305 1788
+4786 1725
+1180 83
+2889 629
+2889 3655
+4580 1897
+4225 3804
+1816 4586
+2490 4576
+3687 2879
+3396 4577
+3396 223
+4566 1650
+2229 3884
+2750 3262
+2373 4682
+4026 2186
+4434 1408
+3386 3470
+4004 4235
+2991 4503
+555 4230
+3415 4528
+3415 3854
+3854 4528
+4658 4515
+109 1237
+4392 1093
+2691 4392
+1925 4738
+4629 2026
+4522 3199
+112 536
+4565 4020
+490 2545
+1416 346
+2536 2940
+1828 53
+3245 4411
+4048 1994
+4068 251
+121 3940
+2735 107
+4084 107
+2464 2694
+1442 4619
+2317 3037
+2073 180
+432 3097
+1640 4442
+3855 4442
+2346 1784
+3288 657
+4644 1711
+4467 4337
+3974 4266
+4641 831
+2404 4474
+3397 842
+799 4030
+957 4561
+211 3569
+958 4703
+2347 2019
+93 2019
+940 921
+3277 3457
+1542 285
+2489 1574
+4286 4738
+2810 757
+757 3223
+3735 2719
+2770 2719
+365 4212
+2979 4287
+1523 2545
+1523 4626
+4772 868
+4633 4449
+3969 4370
+160 317
+4589 4504
+2857 4790
+4612 4619
+3024 4356
+4726 4787
+1117 3478
+4753 3028
+3081 4095
+1936 975
+2234 3134
+4293 3134
+2919 3681
+639 2353
+3469 1064
+679 273
+1265 535
+3669 1283
+4444 1454
+4627 1803
+4535 4016
+256 2651
+3954 1730
+744 835
+3618 835
+1741 4317
+4586 1729
+3231 1283
+1523 490
+1691 2528
+4346 2489
+3431 3486
+4761 4488
+4753 4775
+4248 4775
+3244 4010
+4721 3893
+1254 1353
+1246 4703
+2639 4775
+1011 4211
+4500 2755
+4624 629
+4643 1345
+817 4305
+1340 3648
+461 2396
+1247 4013
+3407 4013
+1861 2658
+4747 4580
+1440 4140
+3458 822
+4508 2755
+353 3261
+4510 2734
+1408 4436
+4237 1804
+4131 4644
+2622 4630
+2622 3349
+4469 3324
+4786 3324
+3780 3664
+1265 4660
+452 4777
+2936 536
+1091 3902
+1089 3902
+3513 3111
+2715 4556
+4728 4556
+4728 2715
+4216 2688
+3427 3375
+3647 2257
+2959 4695
+941 4414
+1016 3117
+2028 4629
+4397 4775
+1822 4619
+3288 2288
+3471 4768
+3212 2218
+2218 3213
+1398 2800
+1200 4788
+1200 4720
+3609 4775
+4615 904
+1828 4333
+3404 2830
+2002 3404
+3513 1038
+1018 3973
+3605 4715
+4333 53
+799 4224
+1535 3052
+3561 2137
+4628 4561
+3053 4630
+4346 4543
+623 4431
+1271 2246
+4154 3451
+2030 780
+2179 3546
+3896 4706
+334 2684
+3630 4787
+3462 4687
+4331 2004
+940 4691
+3534 3299
+375 3534
+1158 1465
+4213 1579
+3605 2396
+3694 931
+2763 102
+799 4383
+1738 4337
+3593 1791
+3660 4116
+4766 2950
+2407 4278
+1637 1853
+2423 333
+4688 4297
+2208 4053
+2237 4538
+2288 657
+4171 4211
+1042 4315
+3546 2178
+4233 3111
+27 4305
+3639 530
+2542 4418
+2967 3534
+938 2030
+3458 1865
+2098 4268
+1585 2760
+1587 2760
+1349 324
+4448 1839
+4387 1839
+2615 4642
+2615 4044
+4770 395
+3827 543
+4270 1440
+4748 4557
+1040 4315
+3321 4706
+3753 3057
+4189 818
+4270 4140
+3477 2204
+597 2421
+2580 710
+2984 2805
+4706 1610
+3793 1136
+3531 4474
+2536 3016
+2651 2452
+4750 4009
+1650 374
+1377 4412
+3531 2404
+1 2 3
+4 5 6
+7 8 9
+10 11 12
+13 14 15
+16 17 18
+19 20 21
+22 23 24
+25 26 27
+28 29 30
+31 32 33
+34 35 36
+37 38 39
+40 41 42
+43 44 45
+46 47 48
+49 50 51
+52 53 54
+55 56 57
+58 59 60
+61 62 63
+64 65 66
+67 68 69
+70 71 72
+73 74 75
+76 77 78
+79 80 81
+82 83 84
+85 86 87
+88 89 90
+91 92 93
+94 95 96
+97 98 99
+100 101 102
+103 104 105
+106 107 108
+109 110 111
+112 113 114
+115 116 117
+118 119 120
+121 122 123
+124 125 126
+127 128 129
+130 131 132
+133 134 135
+136 137 138
+139 140 141
+142 143 144
+145 146 147
+148 149 150
+151 152 153
+154 155 156
+157 158 159
+160 161 162
+163 164 165
+166 167 168
+169 170 171
+172 173 174
+175 176 177
+178 179 180
+181 182 183
+184 185 186
+187 188 189
+190 191 192
+193 194 195
+196 197 198
+199 200 201
+202 203 204
+205 206 207
+208 209 210
+211 212 213
+214 215 216
+217 218 219
+220 221 222
+223 224 225
+226 227 228
+229 230 231
+232 233 157
+234 235 236
+237 238 239
+240 241 242
+243 244 245
+246 247 248
+249 250 251
+252 253 254
+255 256 257
+258 259 260
+261 262 263
+264 265 266
+267 268 269
+270 271 272
+22 273 274
+275 276 277
+278 279 280
+281 282 283
+284 285 286
+287 288 289
+290 291 292
+293 294 295
+296 297 298
+299 300 301
+302 303 304
+305 306 307
+308 309 310
+311 260 312
+313 314 315
+316 317 318
+319 320 321
+322 323 324
+325 326 327
+328 329 330
+331 332 333
+334 335 336
+337 338 339
+340 341 342
+343 344 345
+346 347 348
+349 350 351
+352 353 354
+355 356 357
+358 359 360
+361 362 363
+364 365 366
+367 368 369
+370 371 372
+373 374 375
+376 377 378
+379 380 381
+382 383 384
+385 386 387
+388 389 390
+391 392 393
+394 395 396
+397 398 399
+400 401 402
+403 404 405
+406 407 408
+409 410 411
+412 413 414
+415 416 417
+418 419 207
+420 421 422
+423 424 425
+426 427 428
+429 430 431
+432 433 434
+435 436 437
+438 439 440
+441 442 443
+444 445 446
+447 448 449
+450 451 452
+453 454 455
+456 457 458
+459 460 461
+462 463 464
+465 466 467
+468 469 470
+471 472 473
+474 475 476
+477 478 479
+480 292 481
+482 483 484
+485 486 487
+488 489 490
+491 492 493
+494 495 496
+497 498 499
+500 53 501
+502 503 504
+505 506 507
+508 509 510
+511 512 513
+514 515 516
+517 518 519
+520 521 522
+523 524 525
+526 527 528
+529 530 531
+532 533 534
+535 536 189
+537 538 539
+540 541 542
+543 544 545
+546 547 548
+549 550 551
+552 553 554
+555 556 557
+558 559 560
+561 562 563
+564 565 566
+567 568 569
+570 571 572
+573 574 575
+576 577 578
+579 580 581
+582 583 584
+585 139 586
+587 588 589
+590 591 592
+593 594 595
+596 597 598
+599 600 601
+602 603 604
+605 606 607
+608 609 610
+611 612 613
+614 615 616
+617 618 619
+620 621 622
+623 624 625
+626 627 628
+629 630 631
+632 633 634
+635 636 637
+638 639 640
+641 642 643
+644 645 505
+646 647 648
+649 650 651
+652 653 654
+655 656 657
+658 659 660
+661 662 663
+664 665 666
+667 668 669
+670 671 672
+673 674 675
+676 677 678
+679 680 681
+682 683 684
+685 686 687
+688 689 690
+691 692 693
+694 695 696
+697 698 699
+700 701 702
+703 704 705
+706 13 707
+708 709 710
+711 712 713
+714 715 716
+717 718 719
+720 721 722
+723 724 725
+726 727 728
+729 730 731
+732 733 734
+735 736 737
+738 739 740
+741 742 743
+744 745 746
+747 748 59
+749 750 751
+752 753 754
+755 756 757
+758 759 760
+761 762 763
+764 765 766
+767 768 769
+770 771 772
+773 774 775
+776 777 778
+779 780 781
+782 783 278
+784 785 786
+787 788 789
+790 791 792
+793 794 795
+796 374 797
+798 799 800
+801 802 803
+804 805 806
+807 808 809
+810 811 812
+813 814 815
+816 817 818
+819 820 821
+822 823 824
+825 826 827
+828 829 579
+830 831 832
+833 834 835
+836 837 838
+839 840 841
+842 843 844
+845 846 847
+848 849 850
+851 852 853
+854 855 856
+857 858 859
+860 861 862
+863 864 865
+866 867 868
+869 5 870
+871 872 873
+874 875 876
+877 878 879
+880 881 882
+883 884 885
+886 887 888
+889 890 891
+892 893 894
+895 896 897
+898 899 900
+901 902 903
+904 905 906
+907 908 909
+910 911 912
+913 914 915
+916 917 918
+919 920 56
+921 922 923
+924 925 926
+927 928 929
+930 931 932
+933 934 935
+936 937 938
+939 940 941
+942 943 944
+97 945 946
+947 948 949
+950 951 952
+953 954 955
+956 957 958
+959 960 961
+962 963 964
+524 965 966
+967 968 969
+970 971 972
+973 974 975
+976 977 978
+979 980 981
+982 983 984
+985 986 987
+988 989 990
+991 992 993
+658 994 995
+996 997 998
+999 1000 1001
+622 1002 1003
+1004 1005 1006
+1007 1008 1009
+1010 1011 1012
+1013 1014 1015
+1016 1017 1018
+1019 1020 1021
+1022 1023 1024
+1025 874 1026
+1027 1028 1029
+1030 800 1031
+1032 1033 1034
+1035 1036 1037
+1038 1039 1040
+1041 1042 1043
+1044 1045 1046
+1047 1048 1049
+1050 1051 1052
+1053 1054 1055
+1056 1057 1058
+1059 1060 1061
+494 1062 1063
+1064 1065 1066
+1067 1068 1069
+1070 1071 1072
+1073 1074 620
+1075 1076 1077
+1078 1079 1080
+1081 1082 1083
+1084 1085 1086
+1087 1088 1089
+1090 1091 1092
+1093 1094 1095
+1096 1097 1098
+1099 1100 1101
+1102 1103 1104
+1105 1106 1107
+1108 1109 1110
+1111 1112 178
+1113 1114 1115
+1116 1117 1118
+1119 1120 1121
+1122 1123 1124
+549 1125 1126
+1127 1128 1129
+1130 1131 1132
+1133 1134 1135
+1136 1137 1138
+1139 1140 1141
+1142 1143 1144
+1145 1146 1147
+1107 1148 1149
+1150 1151 1152
+1153 1154 1155
+1156 1157 581
+1158 1159 1160
+1161 1162 1163
+1164 1165 1166
+1167 1168 1169
+1170 1171 1172
+1173 1174 1175
+1176 1177 1178
+1179 1180 1181
+1182 1183 1184
+1185 1186 1187
+1188 1189 1190
+1191 1192 285
+1193 1194 1195
+1196 1197 1198
+704 1199 1200
+1201 1202 1203
+1204 1205 1206
+1207 251 1208
+1209 1210 1211
+1212 1213 1214
+1215 1216 1066
+1217 1218 1219
+1090 1220 1221
+1222 1223 1224
+1225 1226 1227
+1228 1229 1230
+1231 1232 1233
+1234 1235 1236
+1237 1238 1239
+1240 1241 1242
+1243 1244 1157
+1245 1246 1247
+1248 1249 1250
+1251 1252 1253
+1254 1255 1256
+1257 1258 1259
+1260 1261 1262
+1263 1264 1265
+1266 1267 1268
+1269 1270 1271
+1272 1273 1274
+1275 1276 1277
+1278 1279 985
+1280 1281 1282
+1283 1284 1285
+1286 1287 1288
+1289 1290 1291
+1292 844 1293
+1294 1295 1296
+1297 1298 1299
+1300 1301 1302
+1303 1304 1305
+1306 1307 1308
+1309 1310 1311
+1312 1313 1314
+1315 1316 1317
+1318 1319 1320
+1321 1322 1323
+1324 1325 1326
+1043 1327 1328
+1329 1330 626
+1331 1332 1333
+1334 1335 1336
+1337 1338 1339
+1340 1341 1342
+1343 1344 1345
+1346 1347 1348
+1349 1350 1351
+1352 1353 1354
+1355 1356 1357
+1171 1358 1359
+1360 1361 1362
+1363 1364 1365
+1366 1367 1368
+293 1369 1370
+1371 1372 1373
+1374 1375 1376
+1377 993 1378
+1379 1380 1381
+1382 1383 1384
+1385 1386 1387
+1388 1389 1390
+1391 1392 1393
+1394 1395 1396
+1397 1398 1399
+1400 1401 1402
+1403 1000 587
+1404 1405 1406
+1407 1408 1409
+1410 1411 1412
+1413 1414 1415
+1416 1417 1418
+1419 1420 1421
+1422 1423 1424
+1425 1426 1427
+1428 1429 1430
+1431 1432 1433
+1176 1434 1435
+1436 1437 1438
+1439 1440 1441
+1442 1443 1444
+1445 831 1446
+1447 1448 1449
+1450 1451 1452
+1453 1454 1455
+1456 664 1457
+1458 1459 1460
+1461 1462 1463
+1464 1465 1466
+1467 1468 1469
+1470 1395 1471
+1472 1473 1474
+1475 1476 1477
+1478 607 1479
+1480 1481 1482
+1483 1484 1485
+1486 1487 1488
+1489 1490 1491
+1492 1493 1494
+1495 1496 1497
+1498 1499 1500
+1501 1502 1503
+1504 1505 1506
+1507 1508 1509
+1510 1511 1512
+1513 1514 1515
+1516 1517 1518
+1519 1520 1521
+1522 1523 685
+1524 1525 1526
+1527 1528 1529
+1530 1531 1532
+907 647 1027
+1533 1534 988
+1535 1536 1537
+1538 1539 1540
+1541 1542 1543
+1544 1545 1546
+1547 1548 1549
+1550 1551 1552
+1553 1554 1555
+1556 1557 1558
+1559 1560 1561
+1562 1563 1564
+393 1565 1566
+1567 1448 1568
+302 1569 1570
+1571 1572 1573
+1574 1575 624
+1576 1577 1578
+1579 1580 1581
+1582 1583 1584
+1585 1586 1587
+1588 1589 1590
+1591 1319 1592
+1593 1594 1595
+1596 1597 1598
+1599 1600 1601
+1602 1603 1604
+1605 1606 1607
+1608 1609 1610
+1611 1612 1613
+948 1614 1615
+1616 1617 1618
+1619 1620 1621
+1622 1623 1624
+1625 1626 1627
+1628 1629 1630
+1631 1632 1633
+1634 1635 1636
+1637 1638 1639
+857 1640 1641
+1642 1643 1644
+1645 1646 1647
+1648 315 1649
+1650 650 1651
+1652 915 1651
+1653 1654 1655
+1656 1657 1658
+1659 1660 1661
+1662 1663 1664
+1665 1666 1667
+1668 1669 1670
+1671 1672 1673
+1674 1675 1676
+1677 1678 1679
+1680 1681 1682
+1683 1684 1685
+1686 1687 1688
+1689 1690 1691
+1692 1131 1693
+1694 1695 731
+1696 1697 1698
+1699 1700 1701
+1702 1703 1704
+1705 1706 1707
+1708 1709 1710
+1711 1712 1713
+1714 1715 1716
+1717 1718 1719
+1720 1721 1722
+1723 1724 1725
+1726 1727 1728
+1729 1730 1731
+1732 1733 1734
+1735 1736 1737
+1738 1739 1740
+1741 1742 1743
+1744 1745 1746
+1747 1748 1749
+1750 1751 1752
+1753 1754 1755
+1756 1757 1758
+1759 1760 1761
+1762 1420 1763
+1764 1765 1766
+126 1767 1768
+1769 1770 1771
+1772 1773 1774
+1775 1776 1777
+1778 1779 1780
+838 20 1781
+1782 1783 1784
+1785 923 1786
+1787 1788 156
+1789 1790 1791
+1792 1793 1794
+1795 905 1796
+1797 1798 1799
+1800 1801 1802
+1803 1804 1805
+1806 1807 1808
+1809 1810 1811
+1812 89 1813
+1814 1815 1816
+1817 1818 1819
+1820 1821 1822
+1823 1824 1825
+1826 1827 1828
+1829 1830 1831
+1832 1833 1834
+1835 1836 1837
+1838 1839 1840
+1841 1842 1843
+1844 1845 1846
+1816 654 1847
+1848 1849 1850
+1851 1852 1853
+1854 1855 364
+1856 115 1857
+1858 1859 1860
+1861 583 1862
+1863 1864 1865
+1866 1867 1868
+1869 1870 1871
+1872 1873 1874
+1875 1876 1877
+1878 1879 1880
+1178 1881 1882
+1883 1884 1885
+956 1886 1887
+1888 1889 1890
+1891 1065 1892
+689 1893 1894
+1895 1896 1897
+1898 15 1899
+1900 1901 1902
+1903 1904 1905
+1906 1907 1908
+1909 1910 1911
+1912 1913 1914
+736 1915 1916
+1917 1918 1657
+1919 1920 1921
+1922 1923 1924
+1925 1926 947
+1927 1928 1929
+1930 1931 1932
+1933 1934 1935
+660 1936 392
+1937 1938 1939
+1940 1941 1942
+1943 1944 1945
+1946 1947 154
+1948 1949 1950
+1951 1952 1953
+1954 1955 1956
+1957 1958 1959
+1960 1961 1962
+1963 1964 1965
+1966 1967 1968
+1969 1970 1971
+1972 1973 1974
+1975 1976 1977
+1978 1979 1980
+1981 1982 1983
+1984 1985 1986
+1987 1988 1989
+1990 1991 1992
+1993 1994 1995
+1996 1997 1998
+1999 2000 2001
+2002 2003 2004
+2005 2006 2007
+2008 2009 2010
+2011 2012 2013
+2014 224 2015
+2016 2017 2018
+2019 2020 2021
+1140 2022 2023
+2024 2025 2026
+2027 2028 2029
+2030 1011 2031
+2032 2033 2034
+2035 2036 2037
+2038 86 2039
+2040 2041 2042
+2043 2044 2045
+1882 2046 2047
+2048 2049 2050
+2051 2052 2053
+2054 2055 2056
+2057 2058 2059
+88 2060 1094
+2061 2062 2063
+2064 2065 637
+2066 2067 2068
+2069 2070 2071
+2072 2073 2074
+2075 2076 2077
+2078 2079 2080
+2081 556 2082
+2083 2084 2085
+2086 2087 1123
+2088 2089 2090
+2091 2092 2093
+2094 2095 2096
+1699 2097 2098
+2099 2100 2101
+2102 2103 2104
+2105 2106 2107
+2108 2109 2110
+2111 2112 2113
+2114 2115 2116
+2117 2118 2119
+2120 2121 2122
+2123 2124 2125
+2126 2127 2128
+2129 2130 2131
+2132 2133 2134
+2135 1291 2136
+2137 2138 2139
+2140 2141 2142
+2143 2144 2145
+2146 2147 2148
+2149 2150 2151
+2152 2153 2154
+2155 2156 2157
+2158 2159 2160
+2161 2162 2163
+2164 2165 2166
+2167 2168 2169
+2170 2171 1164
+2172 2173 2174
+2175 2176 2177
+2178 2179 2180
+2181 2182 1481
+2183 2184 2185
+2186 2187 2188
+2189 2190 2191
+2192 2193 2194
+2195 2196 2197
+2198 2199 2200
+2201 2202 2203
+2204 2205 2206
+2207 2208 2209
+2210 2211 2212
+2213 2214 2215
+2216 2217 2218
+2219 2220 2221
+2222 2223 2224
+2225 2226 2227
+2228 2229 2230
+2231 2232 2233
+2234 2235 2236
+2237 2238 2239
+2240 2241 2242
+2243 2244 2245
+2246 2247 2248
+746 2249 2250
+2251 2252 2253
+321 2254 2255
+2256 2257 2258
+2259 1230 2260
+2261 2262 2263
+2264 2265 2266
+2267 2268 2269
+2270 2271 2272
+2273 2274 2275
+2276 2277 2278
+2279 2114 2280
+2281 2282 2283
+2284 2285 2286
+2287 2288 2289
+2290 1818 1858
+2291 2292 2293
+2294 2295 2296
+1689 2297 103
+2298 2299 223
+2300 2301 2302
+1328 2303 2304
+2305 1755 2306
+2307 2308 2309
+2310 2311 2312
+2313 2314 1579
+2315 2316 2317
+2318 2319 2320
+2321 2322 2323
+2324 1039 2325
+2326 2327 2328
+2329 2330 870
+2331 2332 1399
+2333 2334 2335
+2336 2337 2338
+2339 2336 2340
+2341 2342 2343
+2344 1229 2345
+2346 2347 2348
+2349 2350 2351
+2352 2353 2354
+2355 2356 2357
+2358 2359 2360
+2361 2362 2363
+2364 2365 2366
+2367 2368 2369
+2370 2371 2372
+2373 2374 2375
+2376 2377 2378
+2379 2380 2381
+2382 811 2383
+2384 2385 2386
+2387 2388 2389
+2390 2391 1544
+1463 2392 554
+2393 2394 2395
+2396 2397 2398
+2399 2400 2401
+2402 2403 2404
+2405 2406 2407
+2408 2409 2410
+2411 2412 2413
+2414 2415 2416
+2417 2418 2419
+2420 2421 2422
+1359 2423 2424
+2425 2426 2427
+2428 2429 1961
+2430 2431 2432
+2433 2434 2435
+2436 2437 1370
+2438 2439 2129
+2440 2441 2442
+2443 2444 2445
+2446 2447 2448
+2449 2450 2451
+2452 2453 2454
+2455 2456 2457
+1950 2458 2459
+2460 2461 2462
+2463 1015 2464
+2465 2466 2467
+2468 2469 2470
+2471 2472 2473
+2474 2475 2476
+2477 633 2478
+295 2479 2480
+929 2481 2482
+2483 2484 2485
+2486 2487 2488
+2489 2472 2490
+2491 2492 2493
+2494 2495 2496
+2497 2498 2499
+2500 2501 2502
+2503 2504 2505
+2506 2507 2508
+2509 2510 2511
+2512 2513 2514
+2515 2516 2517
+2518 2519 2520
+2521 2522 2523
+2524 2525 2526
+2527 2528 2529
+2530 2531 2532
+2533 2534 2535
+2536 2537 2538
+2539 2540 2541
+2542 2543 2544
+2545 2546 2547
+2548 2549 2550
+2551 2552 2553
+2554 2555 2556
+2557 2558 2559
+2560 2561 2562
+2563 2564 2565
+1007 2316 1100
+366 2566 2567
+2568 2569 2570
+2571 1994 2572
+2573 2574 2575
+2576 2577 2578
+2579 2580 2581
+2582 2583 2584
+2585 2586 1270
+2587 2588 2589
+2590 2591 2592
+2593 2594 2595
+2596 2597 2598
+2599 2600 2601
+2602 2603 2604
+1930 2605 2606
+2607 2608 2609
+2610 2611 2612
+2613 2614 2615
+2616 2617 2618
+2619 2620 2621
+2622 2623 2624
+2625 2626 2627
+2628 2629 2630
+2631 2632 2633
+2634 2635 2636
+2637 2638 2639
+2640 2641 2642
+2643 2644 2645
+2646 2647 2648
+2649 2650 2651
+532 580 2652
+2653 2654 2655
+2656 2657 2658
+2659 2660 2661
+78 2662 2663
+2664 2665 2666
+2667 2668 2445
+2669 2670 2503
+2671 2672 2673
+2674 2084 2675
+2676 2677 2678
+2679 2680 2324
+2681 2682 2683
+2684 674 2685
+2686 2687 2688
+2689 2690 437
+2691 2692 2693
+2694 2695 2696
+2697 2698 2699
+2700 2701 2702
+2703 2704 1634
+2705 2706 2707
+548 1614 2708
+1773 2709 2710
+2711 2712 2713
+2714 483 2715
+2716 2717 2718
+2719 2720 2721
+1211 2722 2723
+2724 2725 2726
+2727 2728 2729
+2730 2731 2732
+2733 2734 2735
+2736 2737 1167
+2738 2739 2740
+2741 2742 297
+2743 2744 2745
+2746 2747 2748
+2749 2750 2751
+2752 2753 2754
+2755 2756 2757
+2758 2759 2760
+2761 2762 2763
+2764 2765 2766
+2767 2768 2769
+2770 2771 2410
+2772 2773 2342
+2160 2774 2775
+2776 2777 973
+2778 2779 2780
+2781 1827 2770
+2782 2783 2367
+2784 2785 2786
+2787 2575 2788
+2789 2790 2791
+2792 2793 2794
+1474 2795 2796
+2797 2798 2799
+2800 2801 2802
+2803 368 2804
+2805 2806 2807
+2808 2809 2810
+2811 1653 2812
+2813 2814 2815
+2816 2817 2818
+2819 2820 2821
+2822 2823 2824
+2825 2826 2827
+2828 2829 2830
+2831 2832 2833
+2044 2834 2835
+2836 2837 611
+2838 2839 2840
+2841 2842 2843
+2844 2845 2846
+2847 2848 2849
+2850 2851 2852
+2853 2854 2855
+2856 2857 2858
+599 2859 2860
+2861 2862 1860
+2863 1563 2864
+2865 2866 2867
+2163 2868 2869
+2870 2871 2872
+2873 2249 2874
+2875 2876 2877
+2878 2879 2880
+2881 2882 2883
+2884 2885 2886
+2887 2888 2889
+2890 2885 2891
+2892 2893 2894
+2895 2896 2897
+2898 2899 2900
+2901 2902 2903
+2904 2905 2906
+2907 2908 2909
+586 2910 2911
+2912 2913 2914
+2915 2916 2917
+2918 2919 2920
+2921 2922 2923
+2924 2925 2926
+2927 2928 2929
+2930 2931 2932
+2933 2934 2935
+2936 2937 596
+2938 752 2939
+2940 2941 2942
+2943 2944 2945
+2946 2947 2948
+2949 1364 2950
+2951 357 2952
+2953 2954 2955
+2956 2957 2958
+2959 2960 2961
+2962 2963 2964
+2965 1728 2966
+2967 2968 2969
+2970 2971 2972
+2973 2974 2975
+2976 2977 2978
+2270 1222 2979
+2980 2981 2051
+2982 2983 2984
+2985 2986 2987
+1570 2988 2989
+2990 2991 2992
+2993 2994 2644
+2995 2996 2997
+2998 2999 3000
+3001 3002 3003
+3004 3005 3006
+2227 1637 3007
+3008 3009 3010
+2688 2450 3011
+3012 3013 3014
+3015 3016 3017
+3018 3019 530
+3020 2447 3021
+3022 3023 3024
+3025 3026 3027
+3028 3029 3030
+289 3031 3032
+3033 3034 3035
+3036 3037 1886
+3038 3039 3040
+3041 858 3042
+3043 3044 338
+3045 3046 3047
+3048 3049 3050
+2015 3051 3052
+3053 3054 3055
+3056 3057 3058
+3059 3060 3061
+3062 1560 3063
+3064 3065 3066
+3067 3068 3069
+3070 3071 1497
+3072 3073 3074
+541 3075 3076
+3077 3078 3079
+3080 3081 3082
+3083 2703 3084
+3085 3086 3087
+3088 3089 3090
+3091 3092 3093
+3094 3095 3096
+3097 3098 3099
+3100 3101 3102
+3103 3104 2861
+3105 3106 3107
+3108 3109 3110
+3111 3112 3113
+2042 3114 3115
+3116 3117 3118
+3119 3120 3121
+3122 3123 3124
+3125 3126 3127
+3128 3129 3130
+3131 3132 3133
+3134 3135 3136
+3137 3138 3139
+3140 2774 3141
+3142 3143 3144
+3145 3146 3147
+3148 3149 3150
+3151 3152 3153
+3154 3155 3156
+3157 3158 3159
+3160 3161 3162
+3163 567 3164
+3165 3166 3167
+3168 3169 3170
+3171 3172 3173
+2291 3174 3175
+785 3176 3177
+3178 3179 3180
+3181 3182 657
+3183 3184 3185
+3186 3187 3188
+3189 3190 63
+8 3191 3192
+3193 3194 394
+2201 3195 3196
+3197 3198 3199
+3200 753 3201
+3202 3203 2162
+3204 3205 3206
+3207 3208 3209
+3210 3211 3212
+3213 3214 3215
+694 1999 3216
+3217 3218 3219
+3220 2415 3221
+3222 3223 1038
+471 3224 3225
+3226 3227 2680
+3228 3229 3230
+3231 3232 3233
+281 3234 3235
+3236 3237 3238
+3239 3240 1080
+3241 3242 3243
+3244 3245 3246
+3247 3248 1212
+3249 3250 3251
+3252 371 794
+3253 3254 3255
+3256 3257 3258
+3259 3260 3261
+3262 3263 3264
+3265 1334 3266
+3267 3268 2497
+3269 3270 3271
+3272 3273 3274
+2964 525 3275
+888 3276 3277
+3278 3279 3280
+3281 3282 3283
+3284 2614 3285
+3286 3287 601
+3288 3289 3290
+3291 3292 1125
+3293 3294 773
+3295 3296 3297
+3298 3299 3300
+3301 3302 3303
+2104 3304 3305
+3306 3307 3308
+3309 1308 3310
+3311 3312 3313
+3314 3315 3316
+3317 3318 3319
+3320 3321 3322
+3323 3324 3325
+3326 3327 3328
+3329 3330 3331
+1973 3332 3333
+3334 3335 3336
+705 3337 3338
+1802 3339 3340
+3341 3342 3343
+3344 3345 3346
+1126 3347 3348
+3349 3350 3351
+3352 3353 3354
+3355 1154 3356
+3357 3358 2876
+3359 3360 2264
+3361 1250 3362
+3363 3364 3365
+3366 3367 3368
+3369 3370 3371
+3372 3373 3374
+3375 3376 3377
+3378 3379 2087
+3380 3381 3382
+3383 3384 3385
+3386 3387 3388
+3389 2364 3390
+3391 3392 3393
+3394 3328 3395
+3396 3397 2700
+3398 3399 1527
+3400 3401 3402
+3403 3404 3405
+3406 3407 3408
+3409 3410 3411
+3412 3413 3414
+3415 3416 3417
+3418 2247 3419
+3420 3421 3422
+2750 3423 3424
+3425 3426 3427
+3428 3429 2078
+3430 3431 3432
+3433 3434 3435
+3436 3437 3438
+3439 3232 3440
+3441 3442 3443
+3444 3445 3446
+3447 3448 3449
+127 3450 3451
+3452 3453 3454
+3455 3456 82
+3457 3458 3459
+3460 3461 3462
+3463 3464 3465
+3466 3467 3468
+3469 3470 3471
+3472 3473 3474
+3475 3476 3477
+2174 3478 2483
+897 3479 3480
+3481 3482 3483
+3484 3485 3486
+585 3487 3488
+3489 3490 3491
+3492 3493 3494
+3495 3496 3497
+3498 3499 3500
+3501 3502 3503
+3504 3505 3506
+3507 3508 3509
+3510 2444 3511
+3512 2014 3513
+3514 3515 500
+117 3516 3517
+3518 2783 3519
+3319 3520 2309
+3521 3522 3523
+3524 823 3525
+3526 98 3527
+3528 3529 3530
+3531 3532 3533
+2903 3534 3535
+3536 3537 3538
+3539 1236 3540
+3541 3542 3543
+3544 3545 3546
+3547 3548 3549
+3550 3551 3552
+3553 3554 3555
+3556 3557 3558
+3559 3560 3561
+3562 3563 3564
+3565 3566 3567
+2696 3568 3569
+3570 3571 3340
+3572 74 3573
+3574 3575 3576
+3577 3578 3579
+3580 3581 3582
+3583 3584 3585
+3586 3587 3588
+2862 3589 3590
+3591 1931 36
+3592 3593 3594
+3595 3596 3597
+3598 3599 3600
+3601 3602 3603
+3604 370 3605
+3606 3607 3608
+3609 3610 3611
+982 3612 3613
+3614 3615 3616
+3617 1255 3618
+2716 3619 3620
+39 3621 3622
+3623 3624 3625
+3626 3499 3627
+3628 3629 3630
+3631 3632 3633
+936 3634 3635
+3496 3636 3637
+3638 3639 3640
+3641 1779 397
+3642 3643 3644
+1351 350 3645
+3646 3647 3648
+3649 3650 3651
+3652 3653 3654
+3655 3656 3657
+3658 3659 3660
+1962 3661 3662
+3663 3664 3665
+3666 3667 3668
+3669 3670 3671
+3672 3673 673
+3674 3675 3676
+812 3677 3678
+3679 3680 3681
+3682 3683 3684
+3685 3686 64
+3687 3688 3689
+3295 2630 3690
+1259 3691 3692
+3693 3694 3695
+3696 3697 3698
+3699 3700 3701
+3702 3703 3704
+81 3705 3706
+3707 3708 3709
+3710 3711 3712
+3713 3714 3715
+3716 508 3717
+3718 3719 3720
+3721 3722 3723
+3724 2686 3725
+3726 3727 3728
+3729 3730 3731
+3732 3733 21
+3734 3735 3736
+3737 3738 563
+3739 3740 3741
+3742 3743 3744
+3745 3746 3747
+3748 3749 3332
+3750 3318 3751
+3752 3753 3754
+3755 3756 3757
+504 2128 3758
+3759 3760 911
+3761 3762 3763
+3764 3765 3766
+3767 1985 3601
+3768 3769 3770
+3771 3772 3773
+3774 3775 3776
+3777 3778 3779
+3780 3781 3782
+3783 3784 2547
+3785 3268 3786
+3787 3788 3789
+3790 3791 3792
+3793 3794 3795
+3796 3797 3798
+3799 241 3800
+3801 3802 3803
+3804 3805 3806
+3807 3808 3809
+3810 781 3811
+1003 3812 3813
+3110 3814 3815
+2706 3816 3817
+3818 3819 3820
+30 3821 3822
+3823 2041 468
+3824 3825 3826
+3827 902 3828
+3829 3830 3831
+3832 3833 3834
+3835 3836 3837
+3838 3839 3840
+3841 3842 2273
+3843 3844 1278
+2600 3845 3846
+1219 3847 3848
+3849 3850 3851
+3852 3853 3854
+3855 3856 3857
+3858 3859 3860
+3861 3862 3863
+3864 3865 3866
+3867 3868 3869
+3870 3871 3872
+3873 3874 2608
+3875 3876 3877
+3878 3879 3880
+3881 3882 3883
+3884 3885 3886
+2393 1079 3887
+3888 42 3889
+3890 3891 3892
+3893 2286 3894
+3895 3896 3897
+3898 3899 3900
+3901 3902 3903
+1574 3904 3905
+3906 3907 3752
+3908 3909 2755
+3910 3911 3912
+3913 3914 2910
+3915 3916 3917
+3918 3919 3920
+3921 3922 3923
+708 3924 3925
+1693 3926 3927
+3928 3929 3930
+2637 3931 3490
+3932 3933 3934
+3935 3936 3937
+3938 3939 3940
+3941 3942 3943
+3944 562 3945
+3763 3946 3947
+3948 2610 3949
+3950 3867 3951
+3881 3952 3953
+3954 3955 3956
+3957 974 3958
+3959 3960 1147
+3961 3025 3962
+3963 3964 3965
+3966 3967 3968
+3969 3970 3971
+3972 3973 3974
+3510 3525 3975
+3976 3977 3978
+3979 3980 309
+3981 3982 3983
+3984 3985 3986
+3987 3988 3989
+3990 3991 3992
+1997 3993 3994
+3995 3996 3997
+3998 3999 4000
+4001 4002 4003
+3987 4004 3483
+4005 4006 4007
+4008 4009 4010
+4011 4012 4013
+4014 4015 4016
+4017 4018 4019
+4020 4021 4022
+4023 4024 4025
+4026 2804 4027
+3388 2997 4028
+4029 4030 4031
+4032 4033 4034
+2928 4035 4036
+1604 4037 4038
+4039 3242 4040
+4041 4042 4043
+4044 4045 4046
+4047 4048 4049
+4050 4051 2379
+542 3076 4052
+4053 4054 4055
+1598 4056 1494
+4057 4058 4059
+3725 4060 4061
+4062 4063 4064
+4065 4066 4067
+4068 4069 4070
+4071 4072 4073
+4074 4075 4076
+4077 4078 4079
+4080 4081 4082
+4083 4084 814
+3448 4085 4086
+4087 4088 4089
+4090 4091 4092
+4093 4094 4095
+2082 4096 2979
+4097 4098 4099
+4100 4101 4102
+4103 4104 4105
+4106 4107 4108
+2606 4109 34
+1503 4110 4111
+4112 1585 4113
+4114 4115 4116
+3897 4117 4118
+4119 4120 4121
+4122 4123 4124
+4125 4126 4127
+4128 3229 4129
+4130 4131 4132
+1713 4133 4134
+4135 4136 4137
+4138 4139 4140
+4141 4142 4143
+4144 4145 1419
+4146 4147 4148
+4149 4150 4151
+934 4152 4153
+3967 4154 4155
+4156 4157 4158
+4159 4160 4161
+1012 4162 4163
+4164 2734 4165
+4166 4167 4168
+4169 4170 4171
+4172 4173 4174
+1317 4175 4176
+4149 4177 4178
+4179 4180 4181
+4182 4183 2408
+2306 4184 4185
+4186 4187 4188
+4189 4190 4191
+4192 4193 4194
+4195 4196 4197
+4198 4199 3742
+4200 4201 4202
+4065 4203 4204
+676 4205 4206
+4207 4208 4209
+4210 4211 4212
+4213 4214 4215
+4216 4217 4218
+4219 4220 4221
+4222 4223 4224
+4225 4226 4227
+4228 4229 4230
+4231 4232 4233
+1327 4234 4235
+4236 4237 4238
+4239 3358 4240
+4241 4242 4243
+3580 1665 3828
+4244 4245 1078
+4246 4247 4248
+4249 4250 4251
+733 4252 4253
+4254 4255 998
+4256 4257 4258
+4259 4260 4261
+4262 11 4263
+4264 3273 822
+4265 1380 4266
+4267 4268 4269
+4270 2268 4271
+4272 4273 4274
+4275 4276 4277
+4278 41 4279
+4280 4281 280
+4282 4283 4284
+4285 4286 4287
+4288 4289 4290
+4291 4292 4293
+3274 4294 4295
+4296 4297 4298
+3374 4299 4300
+4301 1074 4302
+4303 3568 4304
+2639 4305 2729
+729 4306 3028
+4307 4308 4309
+4310 4311 4312
+3818 4313 1381
+4314 4315 4316
+4317 4318 4319
+4320 4321 4322
+4323 4324 4325
+2331 4326 2436
+4327 4328 4329
+4330 4331 4332
+4333 2325 4334
+4335 4336 2500
+4337 4338 4339
+4340 1417 4341
+4342 1620 2965
+4343 3922 1369
+4344 4345 4346
+4347 4348 4349
+2229 4021 2542
+4350 1982 4351
+4352 4353 4354
+4355 4356 4357
+4358 346 4359
+4360 4361 4362
+4363 4364 4365
+4366 4367 4368
+4369 662 4370
+4371 4372 4373
+4374 4375 4376
+4377 4378 4379
+4380 4381 4382
+4383 4384 4385
+4386 4387 4388
+4379 4389 4390
+4391 4392 4393
+3111 4394 4395
+4396 4397 4398
+4399 1750 3799
+4400 4401 4402
+4403 4404 4405
+4406 4407 4408
+4409 4410 828
+4411 4412 4413
+4414 4415 4416
+2869 4417 4418
+4419 4420 4421
+4422 4423 4424
+4425 4426 4427
+1271 4428 4429
+4430 4431 4432
+4433 2598 4434
+4435 799 4436
+4437 4438 4439
+4440 1963 4441
+4442 4443 4444
+1207 4445 4446
+4447 4448 4449
+4450 4451 4452
+4453 4454 4455
+1415 4456 4457
+4458 4459 1932
+4460 4461 4462
+4463 4464 4465
+4466 4467 4468
+4469 1992 4470
+4471 1296 4472
+4473 4474 4475
+4476 4477 4478
+4479 4480 4481
+2529 4081 4482
+4483 4484 4485
+2077 4486 521
+2576 4487 474
+4488 3178 4489
+4249 4490 4491
+4492 4493 4494
+2546 3258 1423
+4495 4496 4497
+4498 4499 4500
+2945 4501 4502
+4503 4504 4505
+1723 4506 4507
+4508 4509 4510
+4511 4512 2340
+120 4513 4514
+4515 4516 4517
+4518 4519 4520
+4521 4522 4523
+4524 1859 4525
+3651 4526 423
+3278 4527 4528
+4529 3896 4530
+4351 1958 4531
+4532 4533 4534
+4535 4536 4537
+4305 4328 4538
+4539 3482 3861
+4540 2522 4541
+4542 4543 2973
+4544 4545 3103
+1861 4546 4547
+4548 4549 4550
+4392 4551 2553
+4552 4553 4554
+4555 4556 4557
+4558 4559 4560
+4561 4562 4563
+4564 4159 4565
+4566 4567 4568
+4569 4570 4571
+4572 4573 4144
+4574 4575 4576
+3001 4577 4578
+4579 4580 4581
+4582 4583 4584
+2260 4585 4586
+4587 3730 4588
+4589 4590 4591
+4592 4593 4594
+4595 4596 4597
+4598 4599 4600
+4601 4602 4603
+4604 4605 4606
+4607 4608 4609
+711 4610 4611
+4612 4613 73
+4614 4615 4616
+4195 1518 4617
+4618 4619 714
+4620 4621 4622
+1379 1306 4623
+4624 1800 4625
+1566 4626 4627
+4628 4629 4630
+651 4631 4632
+4633 3719 2293
+4634 2469 4635
+4636 4637 4638
+235 4639 4640
+4641 4642 4643
+4644 4645 4646
+3480 4647 4648
+3831 4649 1132
+4650 4651 4652
+4653 4654 4655
+4656 4657 3231
+4658 4659 4660
+4333 4661 4662
+4663 3805 1548
+4664 4665 1055
+4666 4667 4145
+4668 4669 4670
+4671 4672 4673
+4674 4675 4676
+4677 4678 4679
+3441 4680 1673
+1562 4681 4682
+4683 4684 4685
+2683 4686 4687
+4688 4689 4690
+4691 4692 4693
+4694 4695 4212
+4696 4697 4698
+4699 4700 4701
+3835 4702 4703
+4704 4705 4706
+4707 4708 806
+4709 4710 4711
+4712 4002 4713
+4714 4715 4716
+1681 4717 4718
+4719 4245 4720
+3653 4721 4722
+4383 951 3838
+4723 4724 4725
+4726 4727 4728
+4729 4730 4731
+4732 4733 4734
+4735 4736 4737
+4738 4739 4740
+4741 4742 4743
+2685 4744 1484
+4745 4746 4747
+4748 4749 4750
+4751 4752 4753
+1983 4754 4755
+2470 4756 4757
+4758 4759 4760
+4761 4762 4763
+4764 4765 1912
+4766 4767 4768
+4769 4770 362
+4771 866 4772
+4773 4774 4775
+4776 4777 4778
+4779 4780 4781
+4782 3581 4783
+4784 4785 4786
+4787 274 4788
+3087 4789 4790
+4791 4792 2746
+4793 4794 4795
+4796 4797 4798
+4799 2636 4800
+2585 4801 4802
+4803 4804 4805
+4334 1745 4806
+4807 4808 4809
+4810 4811 4812
+4813 4814 4815
+4816 3245 4817
+4818 4819 4820
+4821 4822 4823
+4824 4825 4826
+4827 4828 4829
+4830 4831 4832
+4833 4834 4835
+4836 4837 4838
+4839 4840 4841
+4842 4843 4844
+4845 4846 4047
+1714 4847 1616
+4848 4849 4850
+4851 4852 4853
+4854 4855 4856
+4857 2831 1649
+2582 4858 4859
+2735 4860 4861
+1312 1977 2643
+4862 4863 4864
+4865 4866 4867
+4868 1325 1071
+4869 3733 4870
+1502 4871 4872
+1026 4873 4874
+4875 4876 4877
+4878 4879 4880
+4881 2 4882
+4258 4883 4884
+4277 4885 4886
+4887 4888 2166
+2881 4889 4890
+4891 4892 4893
+1906 4894 4895
+4896 4897 4898
+4899 4900 4901
+4902 4903 4904
+3958 4905 4906
+4907 4908 4711
+4909 4910 4911
+4912 4913 4914
+4010 4915 4916
+4917 4918 4919
+4920 2173 3424
+4921 4922 4923
+4924 4925 2888
+37 4926 4927
+4928 4929 4930
+4931 4932 4933
+4934 1350 3527
+4935 4936 4937
+4938 4939 4940
+4941 1952 1361
+4942 3984 4943
+4944 4945 4946
+4947 176 4948
+4949 3160 4950
+4951 824 427
+4952 4953 4954
+4955 4956 1659
+4957 4958 4959
+4960 4961 4962
+2860 3046 4963
+4964 4965 4966
+4967 4968 4969
+1710 4970 4971
+4972 472 4973
+4974 4925 4975
+4976 4977 4978
+4979 4980 4981
+1194 4982 3373
+4983 3533 4984
+4985 4986 4987
+4988 1398 4989
+699 4990 3969
+719 4991 4992
+4993 4994 2063
+4995 4996 3823
+4997 4998 4999
+2541 5000 5001
+5002 5003 5004
+3951 5005 5006
+5007 5008 5009
+5010 5011 5012
+5013 5014 4854
+5015 5016 2220
+5017 3017 5018
+5019 5020 5021
+5022 5023 5024
+5025 5026 5027
+5028 345 5029
+3487 5030 3144
+5031 5032 5033
+5034 5035 5036
+5037 5038 5039
+3365 5040 2443
+821 597 5041
+5042 5043 5044
+1587 5045 5046
+5047 5048 5049
+5050 5051 5052
+5053 2283 5054
+5055 5056 2625
+5057 3114 5058
+5059 5060 4866
+5061 5062 5063
+458 5064 4851
+5065 2241 5066
+5067 5068 5069
+5070 5071 5072
+5073 5074 5075
+5076 5077 1087
+5078 2570 5079
+5080 5081 2901
+5082 3011 5083
+2281 5084 5085
+5086 5087 2899
+5088 1670 5089
+5090 5091 1360
+5092 5093 5094
+5095 5096 5097
+5098 5099 5100
+5101 5102 5103
+5104 5105 5106
+5107 4578 2975
+5108 5109 5110
+5111 5112 5113
+5114 5115 5116
+5117 5118 5119
+5120 5121 5122
+5123 5124 5125
+5126 5127 5128
+5129 5130 5131
+5132 5133 5134
+5135 5136 5137
+5138 5139 5140
+1035 5141 5142
+5143 5144 646
+5145 498 5146
+5147 5148 5149
+1735 5150 5151
+5152 3882 5153
+5154 2879 3706
+5155 5156 5157
+5158 5159 5160
+5161 5162 5163
+5164 5165 5166
+5167 5168 5169
+5170 5171 5172
+5173 5174 5175
+5176 5177 5178
+3466 5179 5180
+5181 5182 909
+5183 5184 5185
+5186 5187 5089
+5188 5189 5190
+5191 5192 4732
+5193 2519 267
+5194 5195 5196
+5197 5198 5199
+5200 5201 5202
+5203 5204 5205
+1083 5206 5207
+2136 5208 5209
+5210 5180 5211
+5212 5213 5214
+5215 1177 5216
+5217 5218 2767
+5219 5220 5221
+5222 5223 5224
+5225 1708 5226
+4893 3016 1584
+5227 5228 5229
+1887 5230 873
+5231 5232 5233
+5234 5235 5236
+5237 5238 5239
+5240 5241 2704
+5242 5243 5244
+5245 5246 5247
+5248 5249 5250
+2950 5251 5252
+5253 3778 5254
+5255 2981 5256
+5257 5258 5259
+5260 1910 5261
+5262 5263 5264
+4411 5265 5266
+5267 5268 5269
+4911 5270 5271
+5272 1583 5273
+5274 5275 5276
+5277 1967 5278
+672 3762 5279
+5280 5281 5282
+5283 5284 5285
+5286 4364 4528
+5287 5288 5289
+5290 5291 5292
+5293 5294 5295
+5296 5297 2207
+5298 5299 5300
+5301 5302 5303
+3822 5304 5305
+5306 5307 5308
+5309 119 5310
+5311 5312 5313
+5314 5315 5316
+5317 5318 3157
+1855 5319 1807
+5320 5321 1238
+5322 5323 5324
+245 5325 3645
+1785 5326 5327
+5328 3999 5257
+5216 5329 5330
+5331 5332 5333
+5334 5335 5336
+5159 5337 5338
+5339 5340 1070
+5341 5342 5343
+1685 5344 5345
+5346 5347 760
+5348 5349 5350
+5351 5352 5353
+2815 5004 5354
+5355 5356 5357
+5358 5359 5360
+5361 3188 5362
+3556 5363 5364
+5365 5366 5367
+420 227 5368
+5369 5370 5070
+4791 5371 2940
+2355 5372 5373
+718 5374 4445
+5375 5376 5377
+5378 1261 5067
+4188 5379 5380
+725 5381 5382
+5383 5384 5385
+5386 238 3185
+5387 5294 3402
+5388 5389 5390
+5391 5392 5393
+5394 5395 5396
+5397 5398 5399
+5400 5401 5402
+5403 3578 5404
+5405 5406 5407
+5408 5409 5410
+5411 5412 5413
+3595 5414 5415
+5416 5417 5418
+1151 1262 5419
+5420 5421 5422
+5423 5424 4487
+5425 5426 5427
+5428 5429 5430
+3048 5431 5432
+1851 1017 5433
+5434 5435 5436
+4284 5437 3704
+2279 5438 767
+5439 380 5440
+5441 5442 5443
+2920 5444 5445
+5446 5447 5448
+5449 5450 5451
+2622 5452 5453
+5454 5455 5456
+5457 5458 5459
+5460 5461 5462
+5463 5464 3375
+5465 5466 5467
+5468 5469 5470
+1282 5471 5472
+5473 5474 5475
+5476 4201 2826
+5477 5478 1339
+5479 5480 4542
+5481 5482 5483
+5484 4604 5485
+2962 5486 5487
+5488 5489 5490
+5491 5373 5492
+5493 3327 3870
+5494 5495 5496
+1288 5497 5498
+5499 5500 5501
+3780 5502 5503
+4092 5504 5505
+5506 5507 5508
+2449 910 5509
+5510 3221 5511
+5512 5513 5514
+497 3630 5515
+4011 5516 5517
+916 5518 5519
+5520 5521 5522
+3435 5523 5524
+5525 5526 5527
+5528 4994 5529
+1793 5530 5531
+5532 5533 5534
+5535 5536 5537
+5538 5539 5540
+5541 5542 5543
+5544 5545 5546
+5547 5548 3005
+5549 5550 5551
+5552 5553 5554
+5555 2566 5556
+5557 1964 5558
+5559 5560 5561
+5562 5563 5564
+5565 17 2406
+3007 4026 2294
+5566 5567 5568
+1595 5569 5570
+5021 5571 5078
+649 5572 5573
+5574 5091 5575
+5576 5577 4845
+5578 3339 5579
+5580 3270 1650
+5581 5582 5583
+5584 5585 1331
+5586 5587 5588
+5589 5590 5591
+5592 5593 5594
+5595 5596 5597
+5598 5599 5600
+5170 5601 5602
+1269 5603 5604
+5605 5606 5607
+5608 5609 5610
+5611 4000 5612
+5613 5614 5615
+5616 2409 1129
+4741 2555 5617
+5618 5619 5620
+5621 5622 5623
+5624 5625 5626
+5627 4881 5628
+5629 5630 5631
+2117 5632 5633
+5634 5635 244
+5636 5637 5638
+5639 5640 5641
+5642 5643 5644
+1940 5645 5646
+5647 5648 5649
+5650 5651 5652
+312 5653 5654
+5655 5656 3875
+5657 5658 5659
+5660 5661 5662
+2305 5526 5663
+5664 5665 5666
+5667 5668 5669
+5042 5670 5671
+1215 5672 5673
+5674 5675 5676
+5677 5678 5679
+5680 5681 5682
+5683 5684 5685
+5686 5687 5688
+3443 3688 5689
+5690 5691 5692
+5693 5694 4882
+5695 5696 5697
+5698 5699 5700
+5701 5702 5703
+5704 5705 5706
+5707 5708 5709
+5710 5711 5712
+5713 5714 5715
+3526 5716 5717
+5718 4982 4122
+5719 5720 5721
+5722 5723 5724
+5725 5726 5727
+5728 1895 5729
+5730 5731 1740
+5732 5733 5734
+2097 5735 2361
+5736 306 5737
+3256 4600 5738
+5739 5740 1508
+5741 3656 5742
+4408 5743 5744
+3637 1949 2858
+5745 3753 5746
+5747 5748 5749
+5750 5751 3658
+5752 5753 5754
+5755 5756 5757
+1876 5758 5759
+5760 5761 5762
+5763 5764 5765
+5766 5767 5768
+5769 5770 5771
+2143 5772 5773
+5774 5523 514
+5775 5379 5776
+5777 5778 4839
+5779 1567 5780
+1655 4727 5781
+5782 3442 5783
+5784 5590 5785
+5786 5787 5788
+5789 5790 5791
+5792 5793 2171
+5794 3801 5795
+5311 5796 2144
+5797 5798 5799
+5800 5801 5802
+5019 5803 5804
+5805 5806 3195
+5807 5808 5809
+5810 5811 5812
+5813 528 5814
+5815 5816 5817
+5818 5819 4461
+4020 2864 4908
+5820 3411 5821
+5822 5823 5824
+5825 5826 5827
+5828 5829 5830
+5831 5832 5833
+1974 5834 5835
+5836 5837 779
+5838 5839 5833
+5840 5841 5842
+5843 5844 5845
+4151 5846 5847
+5848 5849 5850
+5851 5852 5853
+5854 5855 3906
+5856 5857 5858
+5859 5860 5861
+5862 5863 5864
+5865 5866 5867
+5868 5869 5870
+5871 5872 5873
+5874 5875 5876
+5877 5878 5879
+2792 5880 5881
+5882 5883 5884
+3604 23 5885
+5886 4225 3089
+5887 5888 5889
+5890 5891 5892
+5893 5894 5895
+5896 5062 5897
+5898 2721 5899
+4884 5900 5901
+3497 5902 5903
+3356 5904 5905
+4170 5906 5907
+5908 5909 3129
+5808 1315 5910
+5911 5912 5913
+5914 5915 5916
+5917 5918 5919
+1571 5920 5921
+5922 4108 1159
+5923 5924 5925
+5926 5927 5695
+5235 4304 5928
+169 5929 5930
+5931 5932 5933
+5934 2412 5935
+5936 5937 3360
+5938 4948 5939
+5940 4066 5941
+5942 5943 5944
+5945 5946 5947
+5948 5949 5950
+1948 5951 5952
+1515 5953 3849
+5954 5955 5956
+5957 5958 5959
+5960 5961 5962
+5963 5964 5965
+5966 2073 5967
+5968 5003 5969
+5970 5971 5972
+5973 5974 5975
+5976 5977 5978
+5979 5980 5981
+5982 5983 5984
+5985 5986 4244
+1737 5987 5988
+5989 5990 5991
+5992 5993 5994
+5995 5996 5997
+5998 5999 6000
+6001 6002 2396
+6003 6004 6005
+6006 680 1664
+6007 1169 6008
+4589 6009 4566
+6010 5542 6011
+6012 4503 6013
+6014 937 6015
+6016 6017 6018
+6019 6020 3508
+6021 6022 6023
+6024 6025 6026
+5646 6027 6028
+6029 6030 6031
+6032 6020 6033
+1676 6034 4568
+6035 6036 447
+6037 6038 6039
+6040 6041 6042
+6043 6044 4637
+6045 6046 6047
+6048 5321 6049
+6050 6051 6052
+6053 222 6054
+6055 6056 6057
+6058 6059 6060
+6061 6062 5300
+2422 2153 6063
+6064 6065 6066
+3998 6067 6068
+6069 2708 6070
+2632 6071 6072
+6073 6074 6075
+6076 965 6077
+6078 6079 1124
+6080 2895 2468
+6081 6082 1069
+2780 1703 6083
+6084 2745 6085
+6086 3814 6087
+6088 3205 5444
+6089 6090 6091
+5163 5081 3634
+331 3767 6092
+6093 4900 6094
+4263 6095 6096
+6097 6098 6099
+6100 6101 6102
+5468 6103 6104
+3724 6105 6106
+6107 6108 4118
+6109 6110 6111
+6112 6113 6114
+6115 6116 6117
+2198 6118 6119
+6120 6121 6122
+6123 6124 6125
+6126 6127 6128
+6129 6130 6131
+6132 6133 6134
+5475 6135 6136
+1127 6137 6138
+2318 6139 6140
+6141 3530 6142
+6143 6144 6145
+6146 6147 5893
+5412 1623 6148
+341 6149 4466
+6150 1042 6151
+6152 6153 6154
+6155 149 6156
+1013 6157 4470
+6158 6159 3505
+6160 6161 6162
+1888 6163 6164
+1382 6165 6166
+6167 6168 6169
+6170 6171 6172
+6173 1761 2943
+6174 6175 1897
+6176 6177 6178
+5633 6179 6180
+6181 6182 6183
+6184 6185 6186
+6187 6188 6189
+6190 6191 6192
+6193 6194 4310
+6195 6196 6197
+6198 6199 6200
+6201 6202 6203
+6204 6205 6206
+1837 6207 6208
+6209 6210 6211
+6212 6213 2346
+6214 291 6215
+3271 6216 4486
+6172 6217 4315
+1200 6218 6219
+6220 1498 6221
+6222 6223 6224
+6225 6226 5975
+6227 6228 6229
+4134 6230 6231
+6232 6233 6234
+6235 6236 6237
+6238 6239 6240
+6241 6242 6243
+4584 6244 6245
+6246 6247 5956
+6248 6249 6250
+6251 6252 6253
+6254 3437 6255
+6256 6257 6258
+6259 2313 6260
+6261 6262 892
+6263 5055 4546
+6264 3738 3732
+6102 6265 6266
+5916 4922 6267
+6268 3419 6269
+6270 3426 6271
+6272 5087 1822
+6273 6274 6275
+6276 6277 6278
+6279 6280 6281
+6282 6283 6284
+6285 6286 6287
+1086 6288 6289
+6290 6291 6292
+6293 6294 6295
+6296 6297 6298
+6299 6300 1115
+6301 6302 6303
+6304 6305 6306
+6307 3019 6308
+4080 6309 6310
+5525 6311 6312
+6313 1986 6314
+6315 6316 3236
+6317 4685 5562
+6318 5577 6319
+6320 1853 6321
+6322 6323 6324
+6325 6326 6327
+6328 6329 4457
+6330 6331 6332
+6333 6334 6335
+4148 6336 6337
+6338 6339 6340
+5041 6341 6342
+6343 6344 6345
+6346 6347 6348
+6349 6350 3772
+3687 6351 827
+6352 2638 4532
+5925 6353 6354
+955 6355 6356
+6357 6358 6359
+6360 6361 6362
+6363 6364 6365
+6366 6367 6368
+6369 6370 6371
+6372 6373 6374
+6375 6376 6377
+707 6378 2863
+5585 6379 6380
+4135 4763 6381
+6382 6383 5816
+6384 4767 6385
+6386 6387 6388
+301 6389 6390
+6391 6392 4623
+6393 6394 6395
+6396 2200 6397
+6398 1198 6399
+6400 6401 4833
+6402 6403 6404
+6405 6406 6046
+6407 6408 6409
+6410 6411 3060
+4547 6412 6413
+6414 6415 4579
+6416 6417 6418
+6419 5334 6420
+6421 6422 2691
+6423 5314 6424
+6425 6426 6427
+6368 6428 6429
+4121 6430 6431
+6432 6387 6433
+6434 6435 6436
+6437 6438 6439
+6440 4562 6441
+5931 6442 6443
+1061 6444 6445
+6446 5410 4752
+6447 6448 2527
+5592 6449 6450
+405 999 6451
+6452 6453 6454
+3304 6455 2536
+6456 6457 6458
+6459 6460 3965
+6461 4294 6462
+4161 6463 6464
+5843 6465 2816
+6466 6467 6468
+6469 6470 6471
+6472 6473 6474
+6475 6476 6477
+6478 6479 6469
+6480 2218 6481
+6482 6483 6484
+6485 6486 6487
+6488 6489 6490
+5057 6491 6492
+6493 6494 3628
+6495 2369 6496
+6497 6498 6499
+3751 6500 6501
+6502 1554 6503
+6504 6505 6506
+6507 6508 2896
+6509 5619 6510
+6511 6512 5306
+6513 6514 6515
+6516 6517 6518
+6519 6342 732
+6520 5735 6521
+6522 6523 6524
+6525 6526 6527
+6528 6529 6530
+6531 6532 3237
+6533 6534 6535
+6536 6537 5729
+6538 2310 5247
+6539 6540 6541
+5569 6542 6543
+5666 6544 6545
+6546 6547 6548
+4870 6549 6550
+6551 6552 6553
+6554 4384 1266
+6555 6556 6557
+6558 6559 6560
+6561 6562 6563
+6564 6565 6566
+6567 6568 6569
+6570 6571 6572
+6573 6574 6575
+6576 6577 6578
+6579 6580 6581
+6582 6583 6584
+226 6585 4883
+777 1889 6586
+6587 6588 6589
+6590 6591 6592
+969 6593 6594
+6595 6596 4072
+6597 6598 6599
+2747 5206 265
+6600 6601 6602
+6603 6604 6605
+6162 6606 6607
+6608 5381 6609
+5417 2223 6610
+6611 6612 6613
+6614 6615 4458
+6616 6617 6618
+6619 5668 4526
+6620 6621 6622
+602 5572 4632
+6623 6624 6625
+6626 2485 4169
+6627 389 6628
+6629 6630 6631
+6632 4721 6578
+1768 848 6633
+774 6634 6635
+4537 6636 208
+6637 6638 6639
+6640 6641 6642
+6643 2332 3921
+6644 6645 6646
+6647 6648 6649
+6650 2718 4228
+1478 6139 6651
+6652 6653 6654
+6655 6656 6657
+6658 6659 6660
+6661 6597 6662
+6663 6664 6665
+6666 6667 4953
+677 6668 6669
+6670 6671 6672
+6673 6674 6675
+6676 6677 6678
+6679 6089 6680
+6681 2244 4158
+6682 6683 6684
+6685 6686 6687
+6688 6689 6690
+6691 2561 6692
+6693 4389 6570
+6694 6695 6696
+6697 6698 6699
+3807 6700 3469
+6701 6702 6703
+6704 6705 6448
+6706 4338 6707
+6708 4775 5566
+6709 1813 1093
+6710 6711 6712
+6713 6714 6715
+2623 6716 6717
+6718 6719 6720
+5086 6721 6722
+5354 2588 4614
+6723 6724 6725
+6726 6727 5903
+6728 6729 6730
+6731 5841 6732
+6733 6734 387
+6735 5858 6736
+6737 6738 5331
+6739 6740 3366
+6741 6742 100
+6743 3802 6744
+6745 6746 6747
+3744 1512 6748
+2255 1487 6749
+5293 1698 6750
+3602 6751 6752
+2682 6753 6754
+6755 6756 6757
+6758 6759 6760
+6761 6762 6061
+6763 5889 6764
+5528 6765 6766
+2667 6767 6768
+6769 6770 6771
+1690 1466 6772
+6122 6773 1032
+6774 5409 6775
+6776 619 6777
+6778 6779 6780
+6781 6782 6783
+1799 6137 6784
+6785 6786 6787
+6788 6789 2579
+6790 6791 6792
+6793 6794 6795
+6796 6797 6798
+6799 6800 6801
+6746 323 6802
+6803 6804 6506
+6805 6806 6807
+6808 6615 4784
+3097 5694 5492
+6809 6810 6811
+6812 6813 6814
+4710 6815 6816
+5747 6817 6818
+6819 6820 6821
+6822 6823 816
+6824 6825 5405
+6826 6827 6704
+6828 6829 6830
+762 6831 6832
+6833 6834 2562
+6835 6836 4213
+6837 6838 6839
+6840 3364 6841
+6842 6843 3553
+6692 6844 4591
+4079 6845 6846
+6847 6848 6849
+6850 254 6851
+5031 841 6852
+6853 6854 6855
+6856 6857 4506
+2941 6075 270
+6858 6859 6860
+2137 6861 6862
+6863 2692 3593
+6864 6283 6865
+6866 6867 6868
+6869 6870 6871
+6872 2407 6873
+6874 6875 6876
+5393 6877 3905
+6878 6879 6880
+3919 2025 6881
+6882 6205 5976
+6883 6884 6885
+793 6886 6887
+3390 6888 1905
+6889 499 6890
+6891 6892 6893
+478 6894 6895
+6896 6897 6898
+6899 6900 6901
+6902 6903 6904
+3926 5606 6905
+6072 6906 6431
+6907 5096 6908
+6909 6910 6911
+6150 6912 6913
+220 6914 6915
+6916 6917 2403
+6918 6327 6919
+6920 6921 5183
+6922 3844 6923
+6924 6925 6741
+6926 6927 815
+6928 6929 6930
+6931 6932 4626
+263 5265 6933
+6832 5011 6934
+754 6935 6936
+6937 6938 6939
+6940 6941 6789
+6942 6026 6805
+6943 6944 2271
+6945 639 2186
+6946 1120 6947
+6948 436 6949
+6950 780 6951
+6952 3431 6953
+6954 6955 6956
+6957 6958 6959
+6960 6961 6962
+6963 6964 6965
+6966 6967 6968
+6969 6970 6971
+1627 6972 6973
+6974 547 6975
+6976 6977 6978
+6979 6980 6981
+6982 6983 6984
+6985 4970 6986
+6987 5077 6988
+1890 6989 6990
+6991 5425 5017
+6992 6993 6810
+6994 6995 3194
+5673 6996 6997
+6998 6999 3575
+7000 7001 7002
+7003 7004 7005
+7006 4146 7007
+7008 7009 7010
+7011 3344 5856
+7012 2874 7013
+4421 6533 7014
+57 7015 7016
+1806 4585 2344
+4690 3118 6198
+7017 3515 1403
+808 7018 5737
+7019 7020 6098
+7021 5374 7022
+7023 2374 7024
+7025 7026 7027
+7028 7029 177
+7030 7031 7032
+7033 7034 7035
+4472 2739 7036
+3150 6996 7037
+7038 7039 7040
+5885 7041 795
+6728 2017 7042
+7043 7044 6214
+7045 7046 7047
+7048 7049 3813
+7050 7051 7052
+7053 7054 7055
+7056 1440 7057
+1349 7058 7059
+1869 4289 7060
+7061 7062 6213
+7063 5887 2231
+3036 7064 7065
+7066 4657 7067
+7068 7069 7070
+7071 7072 7073
+7074 7075 6958
+7076 7077 7078
+6875 7079 7080
+7081 7082 4162
+3488 7083 5767
+4509 7084 7085
+1073 7049 7086
+7087 7088 7089
+3977 7090 3122
+7091 7092 7093
+3986 3879 195
+4942 7094 7095
+7096 7075 7097
+7098 7099 7100
+7101 7102 7103
+4890 7104 7105
+7106 7107 7108
+4314 7109 7110
+7111 4926 7112
+6631 7113 1738
+7114 7115 6438
+7116 7117 7118
+7119 7120 7121
+7122 7123 7124
+5773 7125 5312
+784 7126 7127
+7128 7129 2094
+7130 7131 7132
+7133 7134 7135
+2381 7136 7137
+7138 7139 7140
+7141 7142 5172
+2016 4879 7143
+7144 7145 7146
+7147 4810 4756
+5260 7148 7149
+7150 7151 7152
+7153 6937 7154
+4248 7155 7156
+7157 1751 4401
+7158 7159 5169
+6445 7160 7161
+7162 7163 7164
+7165 4843 7166
+5269 7167 7168
+6942 7169 7170
+6755 7171 7172
+7173 7174 7175
+7176 7177 7178
+7179 7180 1453
+7181 7182 1316
+2781 5616 7183
+7184 7185 7186
+3506 7187 7188
+7189 7190 7191
+7192 7193 7194
+6560 7195 7196
+7197 2209 7198
+4841 7199 5777
+7200 7201 7202
+7203 3434 7204
+5612 1358 7205
+7206 7207 3961
+7208 7209 7210
+7211 4687 3928
+7212 7213 7214
+7215 7216 5095
+7217 7218 7219
+7220 4206 6536
+6867 7221 1821
+7222 6997 19
+7223 7224 6155
+7225 7226 7227
+7228 6950 7229
+5722 4114 6182
+7230 7231 7232
+3944 7233 526
+7234 7235 7236
+7237 167 7238
+7239 5933 7240
+7241 4805 7242
+3006 7243 6380
+7244 2197 4089
+7245 5875 7246
+7247 7248 7249
+5731 7250 7251
+529 7252 7253
+7254 1234 7255
+7256 3916 1914
+7257 7258 7259
+7260 237 7261
+7262 2612 7263
+7264 7265 7266
+7267 7268 7269
+7270 7271 5587
+7272 7273 2709
+7274 2055 3596
+631 7275 7276
+5821 4220 7277
+7278 7279 896
+7280 6295 7281
+7282 7283 7284
+6 2640 7285
+1660 615 7286
+7287 7288 5080
+7289 7290 6987
+7291 7292 7293
+7294 7295 7296
+7297 7298 7299
+7300 7301 7302
+945 7303 7304
+7305 1522 7306
+3718 7307 7308
+7309 7310 851
+616 7311 7312
+7313 7314 7315
+7316 5363 7317
+7318 7319 7320
+7321 7322 5754
+592 7323 7324
+5310 7325 7326
+7327 7328 7329
+7330 3809 7331
+3872 7332 6344
+4216 7333 7334
+7335 7336 7337
+7338 5589 6125
+7339 7340 7341
+5613 5396 7342
+7343 7079 7344
+7345 7346 7347
+7348 7349 1192
+2849 1706 3806
+7350 7351 7352
+7353 5806 7354
+1725 7355 7356
+7357 2590 7358
+7359 7360 7361
+7018 7362 7302
+7363 7364 7365
+5388 7366 7367
+7368 4830 7369
+7370 7371 1500
+4231 6828 7372
+2690 7373 7374
+7375 7376 5780
+5231 7377 7378
+7379 7380 7381
+3712 7382 3000
+7383 7384 7385
+5651 4426 7386
+7387 7388 3952
+7389 7390 7391
+7392 7393 7394
+7395 7396 5428
+4904 5250 7397
+7398 7399 7400
+972 7250 4976
+7401 7402 7403
+7220 6175 6668
+7404 7405 2959
+7406 606 7407
+7408 3136 7409
+7410 7411 6253
+7412 161 7413
+5757 7414 7415
+7416 7417 7418
+7419 4898 4538
+7420 7421 1951
+464 7422 7423
+7424 7425 7426
+7427 5602 7428
+1871 7429 7430
+7431 7432 7433
+7434 7435 7436
+7437 3566 7438
+7439 7440 7441
+7442 7443 3320
+7444 7445 7446
+7447 7448 7449
+7450 7451 7452
+7453 1180 6543
+1517 7454 7455
+7456 7457 7458
+7459 7460 6955
+7461 7462 5063
+6392 4276 4266
+7463 5366 6487
+7464 7465 7466
+7467 7468 7469
+728 7470 7471
+7472 7473 7474
+7475 7476 7477
+7478 2357 7479
+7480 3152 6588
+6691 7481 7482
+4819 4543 7483
+7484 7485 7486
+7487 2046 4242
+7488 7489 7490
+7491 7492 7197
+3865 7493 7494
+7495 7496 7497
+7498 7499 7500
+4809 7501 5954
+3068 5553 7502
+7503 7504 7505
+4848 7506 7507
+308 6067 7508
+7509 7510 1363
+7511 4501 7512
+7513 7514 5982
+7515 1679 7516
+6288 5490 7517
+7518 7519 7520
+7521 7522 3773
+7523 7524 7525
+4757 7526 6080
+7527 7528 5712
+7529 7530 7531
+7532 7533 7534
+2559 7535 7536
+7537 3161 2875
+7538 7539 4215
+3713 7540 6753
+7541 7542 7543
+7544 7545 1682
+2502 7546 7547
+7548 7549 7550
+7551 4789 7552
+7553 7554 1209
+3395 7555 7556
+7557 7558 7559
+7560 5507 5394
+7561 7562 2233
+3559 7563 7564
+7565 7566 7567
+7568 3453 7569
+415 2022 7570
+7324 7571 7008
+3519 7572 7573
+391 7574 7575
+1552 7576 7577
+7578 7579 7580
+7581 7582 5164
+7583 7584 7585
+7586 6388 1711
+7587 7588 3992
+2096 3216 7589
+7590 1384 2116
+7591 83 7592
+7593 3714 2681
+4412 7594 6050
+7595 7596 7597
+4192 7598 7599
+7600 3197 7137
+7601 6870 7602
+7603 6995 7604
+7605 7606 7607
+7608 2068 7609
+7610 7611 3666
+7612 7613 7614
+2917 7615 6012
+7616 7617 7618
+7619 7620 2949
+7621 7622 7623
+7624 7625 7626
+5600 7627 7628
+4489 7629 7630
+5308 7631 7632
+7633 7634 7347
+7635 7636 7637
+7216 7638 7639
+5660 7640 4260
+7641 7642 4694
+7643 7644 7645
+7646 7510 7647
+7648 7649 3247
+7650 7651 1671
+7652 7653 7094
+7654 7655 7656
+7657 2829 7658
+3220 7659 7660
+7661 843 7662
+7663 7664 7665
+7666 7667 7668
+7669 7670 5129
+2135 3674 7671
+7672 7673 7674
+7675 7676 7459
+7677 4049 7678
+7679 7680 3798
+7579 7681 7682
+7683 7684 7685
+7686 7687 7688
+7689 7690 7691
+7692 3299 7693
+7614 7694 7695
+7696 7697 7698
+7100 7699 7700
+7546 7701 7702
+7703 7704 7705
+7706 7707 7708
+7709 4253 7710
+7711 7712 7713
+7714 3939 7715
+3259 7716 7717
+7718 5550 7719
+7720 7721 6346
+7722 7723 7724
+7725 7726 7727
+7728 6412 7729
+5813 6549 3737
+7730 7731 7732
+333 7733 6314
+7734 7252 7735
+1759 5344 7736
+7737 5389 7738
+25 7739 7740
+7741 3554 7742
+3860 7743 7744
+2676 7745 6663
+7746 487 2732
+7747 7748 7749
+7750 7751 4223
+7752 7753 7754
+7755 7098 7756
+4450 7757 7758
+7759 7760 3107
+6293 7761 7762
+4616 2060 2813
+4476 1783 6843
+7763 7764 7765
+7766 7767 3472
+1607 7768 7769
+7657 7770 7771
+35 7772 7773
+7774 7775 860
+7776 7388 7777
+7778 7779 7780
+7781 7782 7463
+7783 7784 7785
+7786 7787 7788
+7147 7789 7790
+4886 7791 7792
+7793 7794 765
+7795 6575 7796
+7797 3579 7003
+5377 7798 7799
+7800 7801 7212
+7802 7803 7804
+5823 7805 5720
+2319 7806 7807
+7808 7069 764
+2280 1383 7809
+3894 7810 7811
+4424 7812 7813
+7455 7814 4617
+7815 7816 7817
+7818 7819 4596
+7820 7821 7822
+2894 7823 7824
+7825 7826 7827
+7828 7829 7830
+7831 7832 7833
+7834 4233 7835
+7836 7837 4273
+6033 7838 7839
+7840 7841 3403
+7842 7843 7844
+7845 7846 7847
+7848 3250 7849
+2382 6944 5200
+7850 7851 1285
+7852 7853 1891
+2263 7854 7855
+7856 4055 7857
+7858 7859 5598
+7860 5132 7861
+7862 7863 7864
+7865 7866 7267
+7867 7868 2744
+7869 7398 7519
+2609 7870 7871
+7872 7873 7640
+7874 6453 7875
+7876 7877 1596
+2840 7878 7879
+7446 7880 7881
+7882 6390 1953
+7883 7884 7885
+743 7443 7886
+7887 5258 6068
+3061 7888 7712
+7889 7890 7891
+461 7892 7893
+7575 7894 994
+3056 5284 7895
+7896 3335 4224
+7897 2715 7898
+3322 7899 7900
+7901 7902 5441
+1018 6099 7903
+279 7904 7905
+4163 7906 3673
+7907 7908 5278
+7909 3749 7910
+6513 7911 5268
+7912 6128 555
+7913 7914 7915
+7916 7917 7918
+7919 7920 3616
+7921 7922 7834
+7923 7924 7925
+6696 7926 7927
+7928 7929 7930
+3945 7931 7932
+287 2467 7933
+6197 7934 5880
+4086 7935 7936
+7937 7938 7939
+7940 7941 7942
+6981 7943 7944
+7945 7946 7947
+7948 7949 2225
+7950 2215 7023
+5508 5162 1777
+7316 7951 7952
+1532 7953 7910
+7954 6662 5092
+7955 7956 7957
+7958 7959 7960
+7961 7962 5762
+7963 6892 7964
+7965 7966 2453
+4969 7967 1873
+7968 7969 3995
+5074 6367 7970
+7971 7972 904
+4023 7973 7974
+7975 4157 7976
+7977 7978 7979
+7357 7980 1179
+7981 4126 4802
+7982 7983 7984
+7985 7986 7987
+7988 3779 3570
+7989 2348 7990
+7991 4980 1186
+3736 7992 7993
+7652 7994 1990
+7995 2478 7996
+1561 7997 7998
+7999 1739 8000
+4116 8001 8002
+8003 4869 5842
+8004 8005 8006
+5266 8007 536
+8008 5154 8009
+2349 5447 8010
+8011 8012 8013
+8014 256 5356
+8015 8016 8017
+8018 329 8019
+8020 8021 8022
+8023 8024 8025
+8026 8027 1599
+8028 8029 1034
+572 8030 8031
+8032 4004 8033
+8034 8035 655
+8036 4234 6913
+8037 7789 8038
+2142 8039 8040
+8041 8042 8043
+6265 6149 5296
+8044 8045 8046
+8047 4160 8048
+8049 8050 8051
+8052 8053 5847
+8054 561 8055
+1639 8056 2803
+3923 3696 8057
+5988 8058 8059
+8060 8061 710
+8062 6817 8063
+4508 8064 8065
+8066 8067 8068
+8069 7344 8070
+8071 1479 8072
+8073 8074 8075
+465 2922 8076
+8077 8078 8079
+8080 8081 8082
+8083 8084 3914
+8085 8086 8087
+8088 8089 8090
+7729 2627 8091
+2775 8092 2169
+5259 8093 8094
+5171 8095 854
+8096 8097 8098
+8099 8100 8101
+8102 3868 5503
+8103 7222 8003
+8104 8105 4872
+8106 7602 8107
+8108 8109 8110
+7599 7826 7780
+6482 7723 6133
+5836 48 7825
+8111 6865 8112
+8113 5352 8114
+8115 8116 8117
+8118 8119 659
+8120 6165 830
+8023 623 8121
+8122 8123 7401
+8124 558 8125
+5093 8126 8127
+2031 6059 3600
+8128 2842 8129
+8130 8131 8132
+8133 1267 8134
+7700 8135 7756
+8136 8137 3795
+6905 8138 8139
+8140 7604 2595
+1333 8141 8142
+8143 8144 8145
+8146 6553 232
+6778 8147 1286
+3133 8148 8149
+8150 8151 4005
+1883 6976 8152
+1408 8153 8154
+8155 8156 8157
+2397 3106 8158
+8159 3449 8160
+8161 8162 8163
+8164 8165 8166
+6256 8167 8168
+7619 8169 3731
+8170 8123 8171
+8172 8173 8174
+6872 8175 8176
+8177 8178 172
+4675 8179 8180
+8181 2604 8182
+7409 2574 1916
+8183 5748 8184
+8185 8186 7442
+8187 7407 8188
+8189 8190 8191
+8192 8193 8194
+8195 6834 6701
+8062 8196 8197
+8198 8199 6616
+7740 8200 6970
+8201 8202 4961
+8203 8204 697
+8205 8206 3311
+7310 8207 49
+8208 8209 8210
+2642 7235 8211
+8212 4082 1084
+8213 8214 2032
+269 8215 8216
+2095 8217 695
+8218 8002 8219
+8220 6002 7180
+6972 8221 8222
+8223 8224 8225
+4567 8226 5974
+8227 8228 3722
+7356 5761 8229
+8230 3053 8231
+5644 8232 5440
+8233 8234 1193
+8235 8236 8237
+8238 6135 5609
+8239 8240 7982
+5520 8241 8242
+3191 2839 1225
+6037 8243 3516
+7017 8244 8245
+3287 8246 8247
+8248 8249 8250
+6915 3212 5286
+8251 8252 8253
+8254 8255 8256
+8257 8258 8259
+6982 8260 6607
+8261 8262 8263
+8264 8255 8265
+5928 8266 4853
+8267 8095 8268
+1929 8269 1004
+3925 2100 8270
+8271 8272 8273
+8274 8275 8276
+8277 8278 8279
+8280 3786 8281
+1541 8282 8283
+7133 4605 5686
+8284 8285 8286
+8287 8288 8289
+8290 8291 8292
+8293 8294 8295
+8296 8297 8298
+8299 8300 8142
+8301 8302 8303
+8304 3845 903
+8305 8306 8307
+8308 8309 1717
+8310 7893 5446
+8311 2471 1811
+5448 8312 8313
+8314 8315 4342
+2583 8316 8317
+8318 8319 410
+8145 8320 8321
+8322 8323 5991
+8324 8325 8326
+7497 8327 8328
+8329 8137 8330
+8331 5466 2867
+8332 2093 8333
+8334 8335 8336
+8337 8338 8339
+3369 8340 8341
+6362 8342 2125
+8343 8344 8345
+4954 8346 8347
+2304 8348 6373
+8349 8350 8351
+8352 8353 8354
+8355 8356 8357
+8358 8359 1817
+8360 8361 5153
+339 1412 8362
+8363 8364 3265
+8365 3909 8366
+8367 8368 8369
+8370 5323 6042
+8371 4755 8372
+8373 8374 8375
+6993 8376 6201
+8377 8378 8379
+8380 8381 8382
+8383 8384 7400
+8385 8386 8387
+8388 1752 8389
+8390 8391 8392
+5065 4910 8393
+8378 7120 7716
+8394 8395 3463
+3710 8396 8397
+8398 8399 8400
+1030 8401 8402
+8403 8404 8405
+4880 8406 8407
+8408 8409 3255
+7233 8410 1557
+8411 8412 8413
+8414 5305 8415
+8416 8417 8418
+5434 8419 8420
+7609 6773 1688
+3920 6844 8421
+2473 8422 8423
+8424 8425 8426
+8250 8427 8428
+2675 5827 3557
+8429 8430 5173
+8431 8432 8433
+8434 8435 8436
+3297 8437 2819
+8438 8439 8440
+8229 8441 6856
+8442 8443 5693
+4699 8444 8445
+8446 8447 8448
+8449 553 8450
+522 8451 8452
+8453 8454 2064
+4300 8455 6540
+8456 8457 8458
+8459 8460 8461
+7425 8462 8463
+8464 377 8465
+7144 6244 8466
+8467 8468 95
+8031 8469 8470
+8471 8472 4717
+1843 8473 584
+8474 8475 399
+2175 8476 8477
+8478 8479 8480
+8481 8482 8483
+8484 8485 3226
+8486 8487 7865
+3338 8488 8489
+8490 4915 5949
+8491 8492 8493
+8494 5052 8495
+8496 8497 8498
+4718 8499 8500
+8501 8502 8503
+8504 3932 8505
+3517 77 8506
+8507 8508 1868
+8509 3376 8510
+8511 8512 4435
+7724 1469 462
+8513 6376 8514
+455 4024 8515
+8516 8517 3055
+8518 8519 5601
+8520 6011 8521
+2693 8522 8523
+8524 8525 8526
+5749 7491 8527
+8528 5978 8529
+4660 8530 8531
+8532 8533 6598
+8534 8535 8536
+2757 8537 8538
+6749 8539 5918
+4016 3683 8540
+8541 8542 8543
+8544 8545 8546
+8547 8548 8549
+8550 8551 8552
+8553 8554 8555
+8387 5692 8556
+6315 8557 8294
+1672 8558 5783
+8559 7294 8560
+8561 1606 3214
+8562 3096 6739
+8563 7524 8564
+8565 8566 8567
+6417 4863 8568
+5664 8445 1582
+8569 6638 8570
+3768 1054 3359
+8411 8571 8572
+8573 8260 8574
+8575 7821 1458
+8576 5998 8207
+7847 8577 3586
+8578 143 6044
+3953 8579 8580
+8581 5724 8582
+8583 5174 8584
+4369 6544 8585
+8586 8587 8588
+8589 445 8590
+7513 7159 8591
+8238 8592 8593
+8594 8595 8596
+8597 8598 8599
+8600 8601 4966
+8602 8603 8604
+8605 8606 3646
+8607 8608 4896
+1809 8609 6320
+8610 8611 8612
+8613 8614 8615
+1625 8616 8617
+6962 6634 804
+8618 1654 8619
+8620 8621 5245
+8622 3685 8623
+8362 8624 801
+4385 8625 4641
+5960 8626 8627
+8628 8629 8630
+8631 6310 1344
+8632 7117 8633
+4153 8634 8635
+3121 5230 8636
+8637 8638 8639
+1067 7812 8640
+8641 8642 8643
+8644 2507 8645
+8646 8647 8648
+8649 8650 8651
+8652 8653 8654
+4387 8655 7525
+8656 2239 8657
+8658 829 6090
+8659 8190 5986
+8660 8661 8662
+6649 8663 8664
+5882 8665 2873
+8222 8666 8667
+8668 8669 8670
+7124 7901 2057
+1102 7904 8671
+8043 336 8672
+8673 2429 8674
+1277 1265 8675
+8676 1088 8677
+8678 8679 8680
+1470 8601 8681
+8682 4642 8683
+8684 8542 8685
+8686 8687 8688
+8689 8690 4301
+8691 8692 8693
+8694 1501 2111
+8695 8696 6626
+8697 8698 2569
+8699 6505 8700
+8701 8702 1656
+8703 8704 29
+8705 1375 8706
+8707 1956 8708
+3829 5201 6126
+8709 6637 8710
+8711 4237 2530
+8712 255 8713
+3886 7405 8714
+8715 8716 8717
+8671 8718 8719
+2486 8473 101
+8720 2658 8721
+5399 8722 8723
+8724 6938 8725
+3609 8726 8727
+8728 8729 7438
+8730 8731 6934
+8732 8733 8734
+8735 8736 8737
+8738 6341 8734
+8739 4173 8740
+8741 8742 4374
+8743 8744 8745
+8746 3305 2538
+1006 5144 8747
+3705 8748 8749
+8750 1235 8751
+8752 8753 8754
+4323 8755 7271
+3901 8756 8757
+8758 8759 8760
+8761 8762 8350
+8763 8764 8765
+327 609 1302
+8766 8001 8767
+1323 8348 8768
+8769 8770 8771
+1874 8772 2416
+202 8748 8773
+3660 7160 8774
+2045 8775 6281
+8776 8777 8778
+99 8779 8780
+8781 6702 4271
+8782 3911 2009
+3757 8783 8784
+8785 8786 8787
+8788 8789 511
+4919 8790 457
+8791 8792 8793
+8794 8795 2043
+7993 8796 7935
+8797 8798 8799
+8800 2029 8801
+8802 14 8803
+1239 2977 8804
+8805 8806 8807
+7948 2296 8808
+1922 8809 8810
+8811 8812 918
+2733 8813 8814
+8815 8816 8817
+8818 8819 8820
+8821 8822 1551
+8823 8824 8825
+4581 8826 8827
+8828 8829 8830
+1439 8831 6727
+2398 8832 8131
+434 8833 4714
+8834 8835 8836
+4923 8837 2383
+6532 8838 8839
+8840 8841 8842
+1547 8843 2210
+8844 5403 5655
+6965 8845 8846
+6287 8847 5900
+8848 8849 8850
+8851 8852 6396
+8853 8854 8855
+8856 8857 8858
+8859 8860 7248
+8861 8862 8863
+8864 8865 4901
+8866 8867 8868
+8869 8870 8871
+8435 8872 1686
+8873 8874 8875
+8876 8877 8878
+8879 6854 8880
+8881 8862 8882
+8883 8884 8885
+8886 8262 8887
+4646 5178 5924
+3336 8888 8889
+4316 6218 8890
+8891 8892 8893
+8894 8895 8896
+8897 8898 7430
+8899 8900 7584
+8901 3734 8902
+5540 8903 4211
+5756 8904 8905
+8906 8907 6554
+8908 7134 8909
+8910 8911 8912
+8913 8914 2315
+8915 2871 8916
+6374 8917 8918
+8919 7757 8642
+8920 8921 1701
+8922 8923 8924
+845 6234 8925
+8926 8927 8928
+8929 8930 3371
+8931 8932 8933
+8934 8935 2072
+6717 8936 8843
+1184 8937 8938
+8939 5872 8940
+1385 6229 8941
+8942 6464 3275
+8943 1272 8944
+6776 8945 8946
+2946 8947 8948
+8949 4629 701
+7531 8950 8951
+8952 8953 3569
+8890 8954 8955
+8956 8957 8958
+8959 8960 8961
+5611 8962 8963
+8964 8965 8966
+8967 4620 2401
+1988 5746 1538
+8968 8969 8080
+3018 8970 8971
+8719 8972 8973
+5456 7889 8974
+734 4599 8975
+8554 8976 8977
+8978 7699 8979
+8980 8981 8982
+8983 84 8984
+8985 7989 8986
+8987 6223 8988
+8989 8990 8991
+8992 8993 6566
+8267 8994 8995
+8996 4774 5892
+5185 8997 8998
+8999 9000 6709
+3756 7371 8899
+9001 9002 9003
+9004 9005 9006
+9007 9008 8274
+9009 7788 9010
+4003 9011 1324
+9012 9013 9014
+4171 9015 9016
+2007 9017 9018
+9019 9020 8629
+8593 9021 2809
+4497 9022 9023
+4744 7906 9024
+9025 8187 9026
+1388 8913 9027
+9028 9029 2596
+9030 9031 9032
+9033 6901 9034
+9035 9036 7305
+9037 8779 9038
+9039 9040 9041
+9042 9043 9044
+9045 6644 3279
+9046 9047 4875
+9048 6366 5690
+8828 9049 5107
+9050 9051 9052
+9053 9054 9055
+7202 9056 1075
+9057 7897 9030
+9058 9059 9060
+9061 9062 5904
+9063 4844 9064
+4558 4017 9065
+9066 3520 9067
+9068 9069 2438
+9070 9071 8343
+9072 8501 4743
+9073 9074 9075
+9076 6383 9077
+5874 9078 9079
+9080 9081 9082
+1309 9083 9084
+8493 9085 9086
+9087 9088 9089
+9090 3454 9091
+9092 9093 9094
+9095 1613 4469
+2499 9096 9097
+2006 191 8471
+9098 990 9099
+9100 2423 5328
+9101 9102 6472
+5025 7533 3013
+9103 9104 9105
+61 4559 9106
+9107 9108 9109
+9110 7362 9111
+9112 8499 6394
+9113 9114 9115
+9116 4820 9117
+9118 9119 6178
+9120 7805 9121
+9122 9123 6640
+9124 9125 9126
+9127 8228 9103
+9128 9129 9130
+9131 9132 9133
+9134 305 9135
+9136 9137 9026
+9138 9139 9140
+9141 9142 9143
+9144 4510 4337
+9145 5908 3621
+9146 8937 9147
+9148 9149 9150
+9151 9152 2631
+9153 3283 9154
+4088 8947 9155
+9156 9157 9158
+9159 9160 9161
+5407 9162 2440
+9163 9164 9165
+9166 9167 2399
+8773 9168 9169
+9170 9076 9171
+9172 9173 9174
+3391 9175 9176
+3607 313 9177
+9178 9179 4375
+2465 9180 9181
+9182 4490 1175
+9183 9184 9185
+9186 9187 9188
+9189 9190 7928
+6447 5084 9191
+9192 9193 4622
+5131 9194 953
+4634 9195 8038
+9196 9197 9198
+9199 4619 8502
+6220 8332 7157
+7487 9200 9201
+577 9202 9203
+9204 3143 9205
+9206 1747 9207
+6973 4739 3024
+4200 8321 9208
+4087 8208 9209
+2838 9210 9211
+9212 9213 9214
+1224 9215 9216
+9041 9217 9218
+4419 9219 9220
+9221 9222 9223
+9224 9019 9225
+9226 5658 9227
+9228 9229 8209
+9230 9231 2506
+6245 2820 9232
+9233 9234 4909
+786 9235 9236
+9237 9238 3642
+9239 9240 8668
+9241 9242 2039
+8624 9243 9244
+8833 9245 9246
+9247 9248 9249
+9250 9251 9252
+4197 10 9253
+4668 8317 2428
+9254 3626 9255
+2047 9256 6706
+7431 4239 9257
+9258 9259 9260
+9261 9262 9263
+3370 9264 9265
+9266 9038 9267
+9268 9269 6284
+9270 319 5917
+9271 4746 3119
+27 9272 9273
+9274 970 9275
+2843 3589 9276
+8370 8328 9277
+2818 9278 9279
+7942 9280 9281
+9282 9283 9284
+9285 9286 3657
+2446 7634 9287
+9288 9289 9290
+9291 9292 9293
+9294 9295 9176
+9296 9297 9298
+9299 3631 6088
+9300 9301 9302
+9303 6764 9304
+9305 9306 9307
+9308 9309 9310
+9311 9312 9249
+2053 6268 9313
+9314 9315 9316
+9317 9088 7232
+9318 7026 6783
+9319 9320 9321
+6838 8637 9322
+3824 1707 1572
+9323 9324 9325
+9326 9327 9328
+3573 9329 192
+9330 5223 9331
+9332 9333 8315
+8371 9334 1981
+9335 6252 7763
+9336 9337 3249
+9338 9339 9340
+9341 9342 7581
+9343 3864 3134
+9344 7320 9345
+9346 9347 8290
+9348 9349 3189
+9350 997 9351
+9352 7454 4873
+8245 8089 9353
+9354 9355 9356
+9357 9358 9359
+9360 6275 9361
+9362 4167 9363
+9364 5195 5819
+9365 9366 9367
+9368 4202 1744
+9369 4499 9370
+9371 9372 745
+9373 6991 9374
+9375 7899 9376
+9377 9378 8834
+398 9379 9380
+1289 9381 1865
+5984 9382 9383
+8541 6935 6713
+4113 9384 9385
+9386 8744 9387
+9388 5518 3833
+9389 3856 1814
+8491 9390 9391
+9392 9393 9394
+9395 3695 9396
+9397 5128 9398
+9273 9399 9400
+9401 203 7946
+9402 9403 9404
+9405 4056 9406
+3166 9407 8669
+2489 4303 9408
+9409 9410 9411
+4560 3190 9412
+9413 9414 9415
+9416 4689 8340
+5935 9417 9418
+8252 9419 9420
+2890 9421 9422
+9423 5479 4577
+9424 3982 9425
+8774 9426 9427
+9428 5826 9429
+9430 9431 9432
+9433 5026 9434
+6436 9435 9436
+744 7611 9437
+6457 9438 9439
+9440 2498 3222
+9441 9442 9443
+1392 9444 4551
+3010 9445 7
+9446 9447 2684
+9448 1531 9449
+9330 5166 9450
+2272 8837 5915
+9451 9452 5728
+6200 9453 9454
+4046 9455 5689
+9456 9457 9458
+1172 9459 6730
+9460 8571 9461
+4625 3571 9462
+9463 9464 9465
+9466 9467 6494
+9468 5341 7912
+9469 9470 9471
+9472 8249 9473
+9474 8403 9475
+9476 9477 9478
+9479 9480 9481
+9482 9483 1405
+9484 5249 9485
+9389 9486 7833
+9487 9488 9489
+9490 1748 6559
+9491 6300 4650
+9492 9493 9494
+9495 9496 3989
+9395 9497 9498
+9499 6820 8574
+493 9500 9501
+3546 9502 8331
+9503 1427 8213
+9504 9505 9506
+9507 5302 4110
+7105 2262 900
+3460 9508 4468
+9509 9510 3708
+8749 9511 9512
+9513 9500 9514
+9515 6650 9516
+9517 4945 9518
+9519 9520 9521
+8498 9522 8337
+9089 8327 9523
+9524 2801 250
+9525 9526 9527
+7055 7550 9528
+9529 9530 9531
+9532 9533 9534
+6521 8921 9535
+9536 9537 9538
+1588 9539 8199
+6771 7382 9540
+2984 9541 1918
+9542 9543 9544
+9545 9546 2884
+4662 9547 2679
+8567 9548 8483
+2059 1804 9549
+9550 2377 9551
+9552 9553 9554
+7839 1313 9555
+8968 9556 7370
+6952 9557 9558
+5139 7551 2074
+9559 9560 1995
+9561 9562 9563
+7038 6642 9564
+9565 6620 9566
+3599 3462 1133
+9567 7187 6159
+9568 4612 9569
+1543 9503 8910
+8582 9570 6633
+9571 9572 4078
+9573 9574 9575
+9576 7504 6164
+978 7534 9577
+9578 9579 9580
+8587 9581 9582
+9583 9584 9585
+8891 7201 9586
+9587 9588 9589
+2897 9590 4635
+9591 9592 9593
+9594 1695 9595
+9596 9597 1264
+4207 6262 9598
+4230 9599 9600
+6104 9601 9602
+9603 9604 9605
+6490 9606 4989
+6651 4554 9607
+9608 8141 9446
+8210 9609 6853
+516 9610 9611
+9612 9613 9614
+7796 4609 7746
+5043 9615 9616
+940 9617 9618
+9231 9040 9619
+9620 8325 9451
+4302 9621 9622
+1455 9623 1202
+9254 9624 4556
+9625 9626 879
+2177 8244 589
+9627 7715 9628
+9629 7150 6123
+6183 9630 6488
+2535 9631 9632
+9633 9634 7314
+337 803 9635
+7958 9636 9637
+9638 4889 3788
+9639 7088 9640
+3854 9641 2545
+9642 3929 9643
+9644 9645 8783
+9646 9647 9648
+6768 1757 6071
+7461 4030 9649
+9650 4028 9651
+7922 8078 6829
+5662 9652 9653
+9654 9655 9656
+9657 9658 9659
+9660 573 3398
+9661 7951 2844
+9662 9663 9664
+9665 9666 4262
+9667 69 9668
+9669 3003 7035
+9670 9671 6604
+9672 8608 9673
+9674 6074 9675
+9676 9677 6325
+6083 9678 4564
+9679 9326 9680
+935 1451 5769
+7950 9681 4799
+9682 9683 9684
+9685 2226 9686
+8805 9687 7028
+8206 4059 9688
+9689 7980 9690
+2556 3264 9691
+5454 9692 9693
+9694 9695 9696
+2766 9697 9698
+1636 7311 9699
+9700 9701 9452
+9702 8396 2999
+9703 9704 9668
+9705 6723 7021
+9706 9707 9708
+7518 9709 9710
+5152 9711 9712
+9713 3041 9714
+9715 90 9716
+9717 9718 9719
+228 9720 9721
+9722 9723 9724
+9725 9726 6535
+5656 9727 9728
+3313 9729 8787
+7718 6269 9730
+9603 9731 9732
+9733 7429 9734
+7969 4456 9735
+6495 9736 2878
+7547 9737 9738
+8511 3266 9739
+9740 9741 7809
+9742 5681 9743
+9744 9745 9746
+7036 9747 9748
+9749 9750 9751
+9752 9753 9754
+6595 1352 9755
+9756 9757 3927
+6646 2994 9758
+9759 9760 9761
+3196 9762 6661
+9763 9764 5365
+9765 9766 9767
+5330 9768 4199
+7308 755 6837
+9769 7595 3771
+9770 9771 9772
+9773 6397 6670
+9774 9775 9776
+2908 2925 9777
+9778 9779 9780
+9781 9782 4555
+8389 8333 9783
+9391 9784 8946
+9785 9786 9787
+3504 3132 8777
+9788 9789 2180
+1753 3281 9790
+9791 9792 882
+9793 5079 9794
+9795 9796 1143
+7975 9797 6681
+9798 4539 216
+3866 1019 9799
+9800 9342 5211
+9801 4748 9802
+928 9803 9804
+9805 9537 9806
+9807 5099 9808
+4275 9809 4265
+9810 4661 9811
+7277 9812 9813
+9814 5458 7593
+9815 9816 9817
+8214 9818 9819
+6243 8444 9820
+9821 9822 477
+9823 8484 9824
+9825 4437 6782
+9826 5530 9827
+7342 9828 5400
+9829 9830 9831
+6156 9832 7633
+2748 9833 9834
+9835 9836 9837
+9838 9839 9840
+4931 6930 9841
+286 9842 9843
+5027 9844 9577
+7428 8519 9845
+9846 9847 9848
+9849 9850 9851
+4627 2526 9852
+396 9853 131
+9854 9855 1217
+9856 9857 3770
+1507 2771 9858
+9859 4106 9860
+5551 9861 9862
+9863 9864 9865
+9866 9867 927
+1095 4615 7339
+7943 3117 4573
+9868 5531 9869
+9870 5625 9871
+9872 9873 2967
+9874 9875 9876
+9877 9878 9879
+9880 3667 2250
+5573 9881 1652
+9571 4372 7573
+9882 3902 5830
+9883 7031 8068
+3100 989 9884
+2023 9885 5071
+9886 8291 9887
+9888 4536 9889
+9890 9891 9892
+9893 4680 9455
+9894 9895 9896
+6030 1525 9136
+9897 5953 9898
+9899 9900 8823
+9901 2461 9902
+9903 3421 6660
+9904 922 9905
+9400 5064 9906
+9907 9908 9288
+7521 7181 4361
+9909 9910 9911
+8605 9912 9913
+6858 8184 9914
+1371 8722 7621
+5210 2955 9915
+4787 8037 9916
+7778 47 9917
+9918 2534 9919
+4985 8488 9920
+9921 9922 8704
+7059 9745 9923
+9924 3296 6261
+9925 9926 7496
+8040 9459 2424
+9927 9473 2992
+9928 9084 4582
+5224 7749 6109
+9929 9930 3652
+9931 9932 9933
+9893 9934 9935
+9936 1241 5277
+9937 9938 9939
+9940 594 9941
+3170 5318 8583
+9942 9943 6019
+4282 9944 424
+4977 5359 9945
+9946 8854 9947
+9948 5571 9949
+428 771 9950
+9951 9952 9953
+9954 9955 9956
+966 9957 9958
+9959 9960 9961
+9962 9963 9964
+5125 2159 9604
+9965 9966 406
+9554 9265 895
+7658 9967 9968
+9969 9970 6918
+5491 8478 9971
+9416 8930 9542
+9972 9973 9974
+5283 3700 230
+9975 5442 5307
+9087 9976 3947
+9977 9978 2058
+9979 7970 6675
+9980 9981 7858
+6466 9982 6209
+4828 9983 7537
+4067 9984 5964
+8515 6302 9985
+6094 9986 8644
+7639 7283 6908
+8952 9987 9988
+9989 3315 2282
+9990 9991 9025
+9992 5861 4511
+9993 9256 9201
+9994 9823 7338
+3047 9995 6056
+3848 9947 9996
+9997 5990 2299
+7883 365 2345
+9998 9999 10000
+10001 772 3524
+8799 10002 10003
+7622 9213 761
+10004 9377 10005
+8427 8013 2856
+10006 8366 7941
+6887 9590 10007
+10008 7063 7562
+4563 5798 2132
+10009 10010 10011
+9336 10012 2966
+2593 10013 9929
+6091 10014 4376
+7024 10015 10016
+10017 8535 5772
+10018 10019 9773
+10020 10021 4513
+10022 3478 10023
+10024 766 4068
+5631 10025 919
+10026 5594 10027
+10028 5881 10029
+1247 10030 10031
+10032 10033 10034
+6241 10035 10036
+342 9508 10037
+10038 10039 8361
+10040 1591 9066
+4916 10041 10042
+2004 10043 10044
+10045 10046 9907
+7013 9372 10047
+10048 10049 10050
+10051 10052 10053
+4418 9406 1597
+6694 10054 10055
+10056 10057 8655
+10058 10059 10060
+3174 10061 10062
+3116 9544 4666
+2853 6526 7321
+7242 6757 10063
+4350 10064 10065
+10066 9764 9429
+10067 10068 10069
+10070 10071 9496
+10072 10073 8640
+10074 7029 8590
+10075 10076 9163
+5120 9727 5404
+7171 10077 10078
+10079 10080 3551
+5837 3201 10081
+10082 8010 10083
+6754 10084 10085
+2898 10086 8271
+5696 10087 4393
+8614 10088 10089
+10090 8881 1280
+6842 10091 9105
+10092 10093 10094
+10095 10096 5090
+5053 10097 10098
+4077 7101 10099
+3272 2698 10100
+10101 7448 4124
+10102 9083 10103
+10104 5290 5932
+10105 6767 3975
+10106 10107 4348
+3692 10108 1416
+6154 10109 10110
+10111 3587 2284
+10112 10113 8409
+10114 920 3972
+4272 10115 6382
+1387 10116 10117
+4525 10118 10119
+1815 9168 80
+10120 8901 10121
+10122 2138 10123
+9699 4956 3084
+9359 6078 10124
+1792 10125 10126
+10127 10128 8028
+3471 3612 10129
+10130 8266 2695
+6611 10131 2334
+10132 1311 10133
+10134 1199 4958
+10135 10136 322
+4036 10137 10138
+10139 4464 5910
+9007 10140 10141
+1480 10079 7842
+10142 10143 8464
+8480 10144 4009
+5338 8309 10145
+10146 9660 10147
+10148 3812 1016
+2778 10149 7327
+4983 10150 10151
+9442 10152 10153
+3671 10154 6372
+10155 6986 6481
+10156 10157 43
+10158 10159 5225
+10160 1749 7230
+10161 10162 9285
+3012 2292 10163
+10164 10165 3784
+10166 8128 7557
+3540 10167 10168
+3177 10169 6224
+10170 10171 10172
+3715 10173 10174
+10175 5902 2857
+10176 10177 1829
+835 10178 10179
+10180 1760 2224
+6919 10039 6657
+10181 10182 3293
+10183 10184 10185
+10186 10068 8099
+10187 4268 10188
+9100 8094 2140
+5669 488 3324
+4824 10189 10190
+10191 5714 469
+6085 10192 2520
+3552 1144 6676
+10193 10194 6722
+10195 10196 8762
+10197 10198 8725
+9212 8285 6831
+10199 1514 10200
+10201 10202 7919
+10203 10204 9620
+10205 7022 91
+10206 10207 8959
+8603 10208 10209
+3467 10210 10211
+10212 8171 10213
+10214 10215 10216
+10217 10218 2671
+9052 10219 2112
+10220 10221 5135
+2914 10222 10223
+10224 7403 10225
+10226 10227 10228
+10229 10230 6379
+10231 10232 2505
+10233 10234 3372
+5795 10235 9002
+10236 10237 10238
+10239 10240 1812
+9902 10241 10242
+10243 10244 3171
+10245 429 10246
+3873 10247 5557
+10248 9243 10249
+425 10250 10251
+10252 8560 136
+6292 10253 10254
+10255 10256 7648
+4125 8810 10257
+10258 6756 6479
+10259 3686 8932
+10260 10261 10262
+4519 10263 10264
+10265 10266 10267
+10268 9309 3918
+114 10269 10270
+10271 7351 7577
+10272 5537 10273
+10274 4553 6255
+949 10275 8691
+8924 7549 10276
+10277 10278 1406
+10279 7846 10280
+6308 10281 10282
+10283 10284 10285
+10286 6923 8425
+10287 10288 1893
+10289 10290 10291
+9207 6152 9198
+10292 10293 7860
+10294 10295 10296
+5750 9427 8159
+10297 8639 1724
+10298 8786 10299
+5431 1495 10300
+10301 8176 3326
+10302 5406 10303
+9514 2753 2430
+10304 5426 10305
+79 9736 652
+10306 10307 10308
+8892 10309 10310
+8004 9357 4453
+10311 8346 6667
+10312 7638 10313
+10314 10315 10316
+10317 9398 10318
+10319 10320 10321
+6949 10322 10323
+10324 5455 600
+10325 5270 10326
+10327 10328 10329
+6426 10330 10331
+10332 10333 234
+7800 10334 6792
+9838 10335 6361
+9085 10336 10337
+8561 10338 10339
+10340 10341 9659
+3039 10125 10342
+10343 6793 9008
+10344 10345 3142
+10346 3362 10347
+8556 3131 5059
+4549 10348 9011
+10349 2577 10350
+10351 10352 8575
+6459 10353 10354
+9450 7539 7747
+10355 10356 2518
+10357 10358 9948
+10359 7452 10360
+10361 10362 10363
+10364 10365 10366
+4522 10367 7967
+10368 10369 10370
+373 10371 10372
+10373 10374 134
+6034 7481 4590
+6977 2516 7498
+7936 10375 10376
+7911 10377 10378
+10379 10380 10381
+8157 10382 5319
+10383 7418 2761
+10384 10385 8628
+2956 10386 3430
+6321 10387 1374
+6731 10388 10389
+10390 4356 10391
+8301 9857 10392
+10393 10394 10395
+5555 10396 2669
+10397 9310 10398
+2880 10399 2782
+8873 10400 7894
+10401 10402 8613
+10403 9477 10404
+10405 8746 10252
+10406 10407 10408
+8092 5243 10409
+7126 10410 10411
+10412 1936 9551
+10413 10414 10415
+10416 10417 3086
+6096 10418 10419
+8048 10420 10421
+8481 10422 10423
+10424 4794 6612
+10425 10284 10426
+10427 10428 10429
+10430 10431 10432
+10433 10434 10435
+4368 3073 10436
+2326 10437 10438
+10439 5347 2773
+10440 385 10441
+9619 10442 8645
+10443 10444 2067
+691 8683 10445
+8570 10446 10447
+9834 1468 10448
+9324 4517 523
+1533 7955 10449
+10450 10451 6013
+10452 9973 10386
+10453 2738 10454
+5863 10455 2893
+10456 10457 715
+3224 10458 726
+10459 7707 10460
+2749 6601 10461
+10462 4825 10463
+10464 10465 10466
+10467 9147 6010
+10468 10469 485
+8310 9587 7329
+10077 4804 4917
+10470 5161 938
+10471 9664 10472
+10473 10474 8984
+9004 10475 9599
+10476 10477 10296
+10478 10479 9654
+5603 7333 9960
+10480 7548 10481
+2648 258 9670
+4481 3429 7516
+10482 10483 388
+10484 668 10485
+10280 7768 10486
+10487 8585 10488
+10489 10490 10491
+10073 6311 10492
+10493 2052 10494
+591 8806 4947
+10495 10496 10497
+10498 10499 10500
+10501 10502 10503
+10504 10505 10506
+10507 10508 10509
+5667 9766 4283
+210 3123 4535
+4347 3433 1441
+10510 10511 2510
+9367 5014 10512
+4261 3301 10513
+7367 7863 10425
+10514 10515 10516
+10517 10518 10519
+2662 8243 7921
+1072 10348 9402
+10200 7292 10520
+5533 10521 3456
+10522 10523 2936
+10524 5661 6303
+9260 7878 10291
+8276 10525 10526
+6725 10527 4446
+9772 10528 2611
+10529 1966 8720
+10530 5315 10531
+10532 7744 10533
+9961 10534 10535
+1204 10536 10537
+2532 10538 1756
+3325 7309 10267
+10539 10540 8077
+3405 10541 10542
+864 10543 10544
+5876 1845 10545
+10546 10547 5763
+4962 10548 10272
+8836 10549 3564
+2113 4396 5061
+10550 10551 10552
+10553 1377 4483
+6959 10554 6564
+6264 837 10555
+10556 10557 10558
+10559 10560 10561
+5890 10562 6528
+8450 1754 10563
+10564 10565 4724
+10566 8792 10567
+10568 10569 10570
+10571 10572 10573
+1727 10574 9337
+2911 10575 10576
+10577 413 7630
+8767 10578 10579
+10580 10581 588
+10582 10583 9964
+8832 10584 10585
+7683 10586 8706
+10587 10408 7348
+10588 10589 10590
+5236 10591 10592
+10593 10594 2651
+6274 10595 10596
+10597 10598 10599
+8354 10600 10601
+10602 5167 9383
+10081 8060 10603
+10604 9071 10605
+10606 4781 10607
+10608 10609 10610
+5862 10611 10612
+6309 3643 10613
+5758 1833 7278
+10614 10615 7991
+10616 8646 5682
+991 10617 4352
+10618 10619 10620
+3717 10621 3234
+1989 6196 10622
+10623 10624 10625
+10626 10627 1729
+10628 10629 10630
+10631 10632 3252
+148 10633 8431
+10634 10635 7234
+5739 509 10636
+10637 3282 5663
+10638 1493 10639
+5142 1252 8152
+10640 10611 6189
+10445 10641 10642
+10643 10644 10645
+10646 10037 3598
+10647 7115 6869
+7411 10648 7288
+2320 6062 10649
+6266 7492 10650
+4885 10651 9120
+8405 2957 3432
+10652 10653 10654
+6184 10655 5535
+10656 10657 10658
+9602 3891 10659
+10660 10661 6029
+9790 10662 10663
+10664 10665 10666
+10667 10668 10669
+3678 10670 10671
+10672 4593 10673
+1299 10674 10675
+10676 10677 10678
+10679 10680 10681
+987 10682 3843
+8212 6410 9613
+10683 10684 10685
+3790 9380 9101
+10686 10687 10688
+10249 10689 3617
+6808 10690 10691
+842 10692 10693
+1797 10694 10695
+10696 288 4946
+10697 5702 9938
+2490 10465 9987
+3050 10698 10699
+10700 1617 10701
+10702 10703 5534
+8215 5959 2240
+10704 1336 10346
+10705 5414 4109
+7419 4500 10706
+10707 8838 6405
+10708 10709 3796
+10342 10710 10711
+10712 10713 8895
+10714 10715 1130
+10716 4165 10608
+1046 5060 10717
+10718 10719 6883
+10720 8335 7542
+10721 10722 1023
+10723 7421 10724
+7091 10725 5674
+10726 10727 10728
+10729 10730 10731
+10732 10733 7257
+10734 4692 10735
+10736 3485 10737
+2110 9836 10738
+9886 7871 570
+7142 10739 8518
+10673 6815 10740
+10741 9404 10742
+2102 10743 9130
+10744 10586 8281
+4287 10745 10746
+2189 10747 10748
+10749 9944 10750
+10751 10085 10752
+10753 10754 10755
+10756 10757 10758
+2923 10759 1170
+10760 10761 10762
+7217 10763 7646
+5636 10764 7155
+10765 10766 3215
+1413 10767 4178
+10768 10769 9656
+10770 2214 3608
+1409 1697 10771
+10772 10687 9789
+7168 10773 8296
+10774 8226 10775
+6273 10776 10777
+10778 3146 1731
+10779 10780 10781
+10782 10783 10784
+10785 10786 10787
+10788 7289 5538
+5870 10789 1917
+10790 10791 10792
+10793 10794 5281
+10795 10796 9740
+8521 10505 10797
+2267 10798 6909
+4329 10799 8486
+10800 10801 6054
+8791 9865 2048
+10802 10803 9979
+8129 10804 10805
+10806 28 10807
+10808 10809 10810
+10032 8135 10811
+625 7437 1578
+1033 10812 10813
+5353 10814 10815
+9314 10816 6147
+5147 10817 2995
+10818 2010 10819
+10820 8061 2938
+10821 10822 10823
+1863 7445 9480
+10824 2212 7122
+4494 2654 10825
+10826 9062 7895
+10827 10828 10829
+10830 10831 10832
+1971 10833 748
+10834 10835 10836
+2789 10483 10837
+6484 5196 1467
+10838 10839 10840
+10841 10842 8906
+6678 10843 7972
+10844 9248 10845
+10846 10847 7808
+9998 10848 10849
+3459 10850 10851
+10852 1366 4840
+10853 10854 10855
+3846 4156 10856
+6517 10857 5940
+4835 10858 10859
+10860 10861 2246
+10862 7535 10863
+10864 10865 5237
+10130 8339 456
+10866 10867 10868
+10869 10870 7291
+10871 1216 8103
+10872 10873 10201
+10874 1053 8732
+10875 6508 6847
+4343 10876 3697
+8650 4142 6787
+10877 10589 10878
+10879 10880 10881
+1692 10882 10883
+2726 10884 9967
+2452 10885 8054
+10886 5104 10887
+10888 10889 10890
+10891 10656 10892
+10893 10894 10895
+8751 10896 10897
+3162 2702 10898
+10899 8016 10329
+10900 10162 10901
+10902 10903 8830
+10904 10905 10906
+2827 9208 8689
+5770 10907 3871
+10908 7041 9916
+540 9219 10909
+10910 10911 10843
+10454 10912 6510
+10913 10914 4796
+10915 10916 10841
+10917 10918 10519
+10919 7920 10920
+10921 9128 10922
+10923 9966 1275
+6606 10924 10925
+10926 10927 10928
+9593 10929 8848
+10930 9844 10931
+10932 6877 10933
+7580 10934 10935
+6845 3895 10936
+10741 10253 5339
+10937 10938 10939
+6028 8381 10940
+412 8758 4488
+10941 185 10942
+10943 3307 5797
+10944 5136 5280
+3850 10945 2725
+10946 10947 1105
+10948 10949 10950
+10951 10761 10952
+5792 9980 7628
+10953 8625 10954
+10955 10956 10957
+5292 6859 7240
+6007 7097 10958
+10959 10960 10961
+10962 5083 9568
+3994 1629 10963
+10964 10965 10966
+1894 3859 10967
+10691 1924 10328
+10968 10969 6439
+10970 10971 8920
+5868 10972 10973
+10974 1301 8883
+5316 10665 10975
+6893 544 10976
+6677 10977 10978
+10979 10980 8531
+6352 10981 10799
+10982 10983 8995
+9894 9917 7882
+8087 10107 10984
+1516 10985 10986
+3193 10987 5725
+10988 10989 10990
+5275 10991 10992
+10993 9891 9655
+9985 9421 7642
+10994 10995 10996
+4838 10997 7178
+10998 8093 10999
+4703 11000 31
+7807 11001 11002
+11003 11004 11005
+5707 11006 8840
+4203 11007 382
+8549 11008 11009
+5620 4033 8509
+5909 10218 10431
+11010 11011 11012
+11013 11014 11015
+10205 2434 11016
+6289 7888 6411
+6456 55 11017
+8379 11018 11019
+11020 9863 11021
+11022 11023 1979
+11024 11025 11026
+11027 11028 9661
+11029 5622 6579
+11030 7195 9206
+11031 5778 11032
+6720 10959 10491
+8980 1524 11033
+11034 11035 11036
+414 11037 9358
+11038 6639 11039
+5588 11040 10513
+10344 11041 4586
+11042 11043 4816
+10246 8200 2580
+10907 11044 7332
+8086 8737 11045
+11046 11014 236
+2794 11047 6195
+7335 11048 2433
+11049 4936 6910
+2302 10733 11050
+9448 8666 9224
+11051 11052 433
+4394 11053 2353
+9154 11054 87
+11055 44 3414
+11056 11057 5199
+5002 11058 11059
+11060 2079 11061
+11062 8452 11063
+11064 6335 10134
+3173 3081 11065
+10178 11066 11067
+1145 11068 5992
+11069 10789 5831
+11070 9562 2439
+11071 11072 1113
+11073 11074 9594
+11075 7690 1341
+9591 11076 11077
+9457 10113 1097
+5371 10448 9364
+11078 2327 11079
+9988 7576 8822
+4737 9423 11080
+11081 11082 4241
+11083 4069 11084
+4198 11085 11086
+11087 2991 11088
+6732 1712 11089
+9820 4701 11090
+11091 11092 3592
+5072 11093 11094
+10791 11095 11096
+4823 9743 2824
+11097 11098 11099
+3789 11100 11101
+11102 11103 11104
+2354 6791 833
+933 5771 8175
+1274 10529 11105
+11106 11107 11108
+4728 11109 11110
+1586 7136 5460
+9396 513 8042
+643 11111 9781
+11112 1060 10984
+11113 11114 5962
+11115 11116 4007
+5036 7389 9774
+11117 11118 11119
+6060 2362 1720
+5615 2902 7560
+9143 5834 11120
+10332 5045 5462
+6655 11121 2373
+11122 10797 4341
+11123 8548 7176
+11124 11125 1112
+11126 11127 11128
+4665 11129 8733
+11130 10506 11131
+3755 2091 6221
+11132 7784 7205
+441 11133 11050
+11134 11135 917
+7011 11136 11137
+11138 11095 11139
+11140 11141 3470
+11142 4140 11143
+11144 3869 11145
+2808 11146 6136
+479 10499 9888
+11147 11148 7375
+11149 11150 4671
+5176 10394 11151
+11152 11153 6263
+537 11154 10585
+9756 8139 9645
+11155 8356 4520
+452 6486 11156
+10533 11157 11158
+11159 5857 11160
+11161 5282 4515
+11162 11163 211
+11164 9505 11165
+11166 5937 11167
+6226 11168 11169
+8130 11170 11171
+11172 11173 11174
+11093 11175 446
+10699 7402 11176
+11177 4730 4386
+7209 8867 9627
+11178 11179 11180
+11181 11182 6514
+11183 11184 11185
+11186 1631 6267
+11187 2071 11188
+11189 11190 10433
+8386 11191 769
+11192 11193 11194
+11195 2219 2248
+5453 11196 6716
+11197 2742 11198
+10350 11199 8713
+11200 11201 11202
+11203 11204 5647
+10440 7838 11205
+4309 11206 11207
+11208 2456 6422
+9456 11209 11210
+11211 11212 11213
+7728 395 7603
+11214 11215 11216
+11217 7866 10397
+4964 1471 11218
+9045 4363 4440
+6734 9411 11219
+11220 11221 11222
+11223 11224 11225
+11226 5415 6021
+11227 8319 2341
+5386 4981 11228
+11229 11230 11231
+11232 8647 11233
+11234 10248 3618
+11235 11236 11237
+4071 2308 1353
+6003 11238 2557
+11239 2037 5345
+10124 3379 11240
+11241 11242 9971
+7845 11243 11244
+10222 11245 205
+11246 11247 11248
+11249 9914 6818
+3615 10171 10872
+8723 1373 7285
+11250 5214 840
+10053 11251 10404
+10601 5796 11252
+11253 2092 11254
+11255 11256 8619
+11257 1425 2918
+11258 8447 7016
+11259 10468 3521
+2743 11260 1396
+11261 11262 11263
+10853 11264 4628
+8588 11265 11266
+4603 7859 11267
+11268 3240 11269
+11270 852 11271
+10721 11272 6945
+6365 9502 2599
+11273 1165 10838
+11274 11275 11276
+11277 2027 11278
+11279 5040 7001
+11280 10543 11281
+8580 2974 11282
+4166 8477 11283
+7300 11284 11285
+688 6441 11286
+11287 11288 11289
+401 7931 10885
+11290 11291 11292
+7261 11293 8164
+9892 11294 11295
+11296 11297 7071
+7924 11298 11299
+11300 6653 11301
+11302 11303 303
+8237 2020 4179
+11304 2495 11305
+3167 11306 787
+1231 11307 7326
+11308 7265 11021
+10681 32 11309
+11022 2076 11310
+8602 11311 11312
+11313 5957 11314
+10121 11315 11112
+11316 11317 7130
+5222 9652 574
+11318 8457 9867
+3830 5343 8052
+11319 5340 6291
+10663 2054 10563
+9236 11320 10410
+11321 11322 2619
+7597 7334 4429
+11323 11324 9712
+9094 11325 11326
+11327 4217 9028
+9720 7272 11328
+4636 11329 11330
+5140 11331 11332
+8107 7114 11333
+11334 11335 9187
+11336 7501 8485
+9858 8928 510
+190 912 163
+5239 5853 8390
+11273 111 1044
+11337 10876 2480
+10003 11338 11339
+11340 11341 4194
+11342 10910 10978
+11343 11344 1240
+11345 2206 11346
+11347 11348 10514
+11349 2086 6047
+11350 4208 10418
+11351 2251 11352
+10908 9195 6886
+3202 10923 11353
+8505 11354 7404
+4988 11355 11356
+9328 1957 11357
+9711 6326 9453
+9585 11358 3991
+5685 6465 3378
+11359 11360 11361
+10660 11362 3168
+5679 11363 11364
+10083 7892 7758
+9495 11365 11366
+9307 11367 5117
+11368 3803 11369
+9462 11370 6538
+11371 1365 11372
+5459 11373 8680
+11374 11375 6794
+10998 3078 11376
+11377 8158 9576
+276 10457 4478
+11378 11379 11380
+9010 5743 3452
+11381 11382 11383
+11384 5251 10763
+1573 2848 11385
+11386 11387 11388
+10767 11389 11390
+9257 11391 10888
+11392 5151 11027
+1237 11393 11394
+266 11395 3137
+9873 1335 7687
+11396 3723 11397
+4876 6216 8352
+11398 4318 11399
+11400 9760 11401
+9850 11402 2343
+11403 10041 8312
+4103 1791 10274
+11205 9943 10628
+11404 9264 11405
+11406 11407 1318
+5545 10455 9118
+9625 11291 11009
+11408 10461 9124
+11409 11410 2850
+11029 11411 3348
+10995 11412 642
+7092 11413 11414
+5430 1459 11415
+9994 1245 11416
+2256 11417 11418
+11419 2762 11420
+11421 1742 11422
+9161 11423 11424
+7795 2731 11425
+9487 11426 10150
+10654 11427 6738
+2980 7368 7848
+11428 11429 5287
+11430 2825 9622
+11431 10195 11432
+2660 11433 5560
+2066 11434 11435
+11436 9919 6473
+11437 11173 11438
+6340 11439 11440
+9911 11441 11442
+11443 5699 11444
+11445 11446 7262
+5570 11447 8770
+3474 2278 3746
+11448 8017 11449
+11450 5565 11451
+6474 11452 11453
+8041 8344 11454
+10686 7545 2178
+8434 8986 11455
+11456 9731 11457
+7503 439 6586
+4264 11458 10177
+4438 7246 11459
+8933 11460 7045
+2378 8925 11461
+5717 11462 9267
+11463 10521 5112
+6143 8918 10452
+11464 9686 11465
+310 11466 11467
+5676 5996 11413
+11468 11469 9210
+11470 11471 11472
+1581 11473 9504
+11474 7193 4780
+10669 9173 11475
+8846 11476 11477
+11478 11479 11480
+72 1429 11481
+717 11482 92
+1549 11483 11484
+2727 4897 1210
+6132 11485 8743
+11486 6204 4790
+11487 4448 11488
+10917 11489 10616
+11490 11491 6608
+4019 11492 8035
+11493 11494 10830
+11495 9560 11496
+5817 4631 11497
+5561 11498 11499
+11500 8885 1337
+11501 6414 11502
+8564 11503 2563
+11504 11505 11506
+6737 11507 11508
+4859 9649 7624
+11509 11510 150
+7350 11511 10573
+684 6069 6882
+11024 11512 11513
+11514 10764 10944
+2441 11515 11516
+9884 11517 9877
+6476 11518 4083
+4442 5784 11519
+11146 2578 11520
+7423 1052 7722
+11521 11241 4008
+9321 1787 11522
+9607 11523 605
+11524 10983 5814
+11525 11526 2405
+11527 9837 7691
+4032 11528 11529
+5271 887 11530
+11531 11532 9149
+11533 7953 9225
+11534 5855 11535
+11536 4968 11537
+6057 173 2404
+11538 11539 11540
+11541 11542 11543
+4062 5626 7050
+11544 11545 9532
+7276 8659 1340
+10967 3955 11546
+11547 4762 482
+8599 926 6936
+10634 9847 11548
+9751 11482 10672
+6786 908 1443
+11549 10377 975
+11550 9644 7583
+3827 11551 4972
+11552 8468 11553
+11554 4311 11555
+2451 3826 3759
+3785 1746 3223
+11556 11557 11558
+11559 11560 8797
+10579 11561 11562
+11563 11564 7851
+3597 10662 7772
+6742 11107 2487
+3990 7738 11565
+10117 11566 11567
+11568 3676 11201
+11569 1610 11570
+11571 7211 4877
+11572 8807 10473
+4803 6215 11573
+325 11574 1669
+11575 11576 11577
+8814 1091 10609
+6654 11578 10214
+3534 11579 7764
+7565 11580 4745
+11581 5056 11582
+5544 11583 7823
+9529 11584 6899
+11585 1643 6015
+10314 8616 3023
+9901 6779 11586
+4269 7184 11587
+9302 11588 11589
+4475 11235 11590
+11591 11592 6819
+11593 1059 11594
+8268 11595 11596
+11597 11598 11599
+3085 11600 11601
+6443 11602 11603
+11604 3797 11224
+7379 259 11605
+11606 11607 11608
+3147 11609 9228
+11610 11611 11612
+11613 11614 11615
+11616 11617 2512
+11618 7198 11619
+11620 11267 11621
+9555 2645 11622
+1775 11623 11624
+7987 11625 1937
+11626 11627 8678
+11628 9581 11629
+4706 11630 11631
+10772 11632 10361
+5639 11633 11634
+10311 11635 11636
+4979 3184 11637
+9053 11638 5351
+11639 11640 11177
+11641 11642 5506
+11643 634 11644
+11645 11646 11647
+8654 11648 11649
+11650 11651 11652
+11653 11654 9194
+10371 11655 7128
+229 11656 10826
+9065 11657 9106
+11658 2365 5934
+11659 9167 11660
+11661 11662 10938
+11663 11664 11174
+11529 2851 3377
+11665 11666 11667
+10257 11668 11669
+11670 11671 11672
+2835 11673 11674
+11675 11676 10396
+10636 8460 6186
+11677 4354 5190
+4583 11678 11679
+11680 11681 11682
+11683 8537 5181
+1293 3384 11684
+9115 11685 11686
+6475 3648 11687
+11688 4749 5700
+11689 11690 11691
+1320 11692 1819
+8211 9771 5397
+11693 11694 10135
+5736 7301 6547
+9969 6656 2832
+11695 5221 1877
+11696 603 9170
+6758 11697 7750
+11698 11699 11700
+1542 4895 11701
+11702 11703 5649
+11704 11705 8306
+11706 6951 10603
+11707 1978 11708
+7605 11709 10553
+11710 11711 7925
+11712 11713 11714
+886 10141 10588
+5494 3974 11715
+9968 11716 11717
+8174 11718 11719
+11720 11721 11722
+11723 9779 9345
+6463 11724 5486
+11725 2289 11726
+8160 11727 11728
+9368 8280 8143
+11045 11576 4349
+682 8528 11729
+11730 11731 11732
+10438 3022 9221
+10678 11272 11733
+9708 11734 11735
+11736 11737 11738
+11739 11740 6671
+3352 11741 11742
+11743 11744 6279
+11065 7684 10243
+5677 7179 1201
+11745 10088 7694
+11746 3550 7971
+6504 9647 11747
+7280 11748 7219
+9384 11749 4473
+2772 11750 11751
+11003 7890 11752
+11753 11754 7806
+5921 3760 3825
+4290 8898 7095
+11755 10287 3693
+11756 11757 11758
+11759 11760 6967
+11761 1770 5564
+10950 11762 11763
+11764 11765 8047
+11766 11767 11768
+11769 11770 10912
+11771 11772 11773
+11774 819 11775
+4832 11776 10316
+9632 1249 7391
+11777 6337 109
+11778 11779 6530
+3130 11780 3936
+10606 11781 9989
+490 11469 8576
+10507 9726 2252
+5402 11579 5614
+11782 6428 11783
+11784 4095 1645
+2581 11785 11786
+5241 11787 11788
+9476 11789 862
+11340 11790 11791
+2352 10179 11792
+11793 1221 9296
+3640 2913 11794
+11795 11796 11797
+3613 11141 11798
+7372 3198 11799
+9159 11708 11800
+9815 11745 11801
+11802 11803 2586
+11804 11805 11806
+2034 1117 8911
+11807 2952 11808
+10509 9786 10559
+10758 11809 6744
+470 11810 11811
+805 11812 11813
+7881 11568 11814
+10010 7843 8879
+9611 9278 5774
+11815 11816 10757
+11817 11818 5009
+11819 10159 10060
+11820 11821 11822
+10836 6719 11823
+10474 11824 10569
+10906 7111 11825
+384 7034 11826
+6673 9048 11827
+9870 8246 11828
+11829 10997 10900
+11830 11831 2906
+9783 11832 11833
+11834 10380 8905
+11835 4252 11836
+4451 460 6076
+737 11837 11838
+11839 11840 11841
+11842 11843 11844
+8949 2295 9878
+11845 742 11846
+1575 4860 11847
+11848 6440 9734
+11849 11850 1789
+1076 9910 3691
+11851 11852 7270
+11853 11854 7060
+11855 11856 723
+9788 11857 1675
+11858 10233 6539
+11859 11860 11861
+6927 10680 6065
+11459 9079 11862
+10024 11863 10846
+809 11864 11372
+11865 8451 9047
+10353 7659 8841
+5385 1008 5733
+11866 4285 11206
+8022 11639 11867
+11868 8755 11869
+1825 9129 11870
+5143 8365 11871
+5776 430 9565
+8136 8046 7852
+1618 10392 11872
+11873 5051 6647
+11874 11069 11875
+961 3427 1218
+11876 11877 11878
+4218 11879 7228
+995 11880 2705
+11113 10299 4827
+8051 11623 10470
+11881 10964 10685
+7655 11882 11883
+10334 11884 7856
+8633 3138 10278
+10294 11885 11886
+2796 11852 11887
+7414 10379 10075
+3183 11888 11889
+11890 11891 11892
+8566 11401 10648
+5193 4250 6084
+6703 11893 4012
+11894 9793 10962
+450 2258 10170
+11895 10471 11896
+5653 7381 6377
+11834 4792 11897
+3728 3938 6953
+11898 11899 11900
+8954 6334 11901
+11902 11903 7062
+11904 7934 1540
+8544 8657 11905
+9950 11906 11610
+11907 5504 11908
+11339 9513 11909
+1195 11910 5141
+10216 11911 6652
+9250 5738 7709
+11912 11913 11914
+11915 11916 11917
+7269 11784 11918
+2019 11919 5965
+3217 6404 11920
+10046 11921 8591
+11385 1447 11922
+10187 9510 11494
+7717 11923 11924
+11925 3043 11926
+11927 11928 11929
+7830 9119 10612
+11930 3343 4935
+4652 10402 8373
+2699 1954 3445
+11931 5313 11932
+11933 11934 703
+5509 9329 4613
+11935 8239 11936
+11937 5219 5972
+2338 5835 9992
+5433 1002 3172
+11938 11939 9687
+3690 11940 9598
+3040 11941 2184
+11734 11942 8516
+10211 11943 11699
+11944 11355 11945
+1156 11946 7473
+11947 11103 11948
+2152 8994 11596
+9479 4366 11949
+2329 3500 9782
+11950 7810 2121
+11951 1534 11952
+5191 6592 10582
+11953 950 11954
+5264 11955 1733
+7977 11956 593
+11957 5753 11023
+11958 3503 6733
+11959 3316 11781
+11960 11961 11962
+11963 9279 11964
+11965 9407 11966
+7110 3423 6170
+10206 10629 11967
+5123 11968 11969
+11970 4696 9146
+11971 9707 9185
+11163 10240 11972
+11034 11973 8769
+9906 11785 7739
+3852 10165 11974
+5865 8880 10602
+11818 11975 9490
+942 11976 11977
+10144 11633 5950
+3962 11978 11979
+8436 6121 9679
+9397 6878 11980
+2664 11981 11982
+9732 11983 11968
+11984 7586 6231
+10639 10259 1838
+5608 11985 10262
+535 11457 11986
+865 11987 10516
+11988 11989 11990
+11222 11991 11992
+8825 8700 11993
+11994 11694 9946
+3542 11995 11996
+4997 687 11997
+381 9408 5234
+4663 10824 9549
+11998 11999 1116
+7191 10375 12000
+12001 12002 12003
+5845 11543 12004
+12005 12006 12007
+1338 11750 8318
+12008 12009 12010
+10825 11407 7559
+418 12011 8510
+12012 3254 12013
+11345 11004 1477
+12014 12015 12016
+11905 2238 5723
+8225 10571 2892
+12017 12018 12019
+6108 1934 10936
+11768 11947 1555
+3912 4404 10961
+6680 9179 9688
+6851 1106 1386
+9802 12020 3088
+12021 12022 12023
+3654 12024 2594
+12025 10427 153
+12026 12027 128
+328 12028 12029
+12030 1346 6862
+2242 4251 8216
+9899 9596 10383
+3668 12027 6904
+409 12031 5477
+4597 12032 5919
+12033 3158 12034
+12035 11044 12036
+12037 3985 12038
+12038 8897 3954
+12039 8417 2548
+12040 9678 758
+11164 3539 11043
+2358 2011 12041
+6619 12042 4063
+11871 12043 4444
+2797 11816 10501
+2958 12044 12045
+6483 8745 2649
+6840 2539 7002
+12046 12047 12048
+3410 442 12049
+8874 12050 9438
+12051 5229 12052
+2656 1968 11344
+11809 2799 12053
+12054 11015 3959
+7815 11084 12055
+12056 12057 9323
+12058 12059 1227
+11728 9666 5751
+12060 10794 4452
+11600 1925 12061
+7341 7820 8999
+1279 1938 10810
+2021 12062 2777
+11491 12063 12064
+9778 125 9344
+2168 6051 2158
+12065 10065 390
+12066 8133 796
+12067 1057 12068
+9488 12069 7966
+11435 10281 8971
+10591 4852 9399
+10750 3703 12070
+1 11402 8442
+4734 10784 6590
+10779 12071 12072
+1601 12073 12074
+693 12075 8682
+5015 9557 3940
+6911 3342 8781
+7264 5075 12076
+12077 9663 4723
+11738 2277 12078
+12079 5912 6248
+5168 12080 12081
+10160 3946 12082
+10740 12083 12084
+6086 3874 10510
+10502 12085 12086
+12087 10668 12088
+12089 10574 6672
+7048 2960 12090
+12091 12023 5911
+7007 12092 12093
+12094 4894 6238
+12095 12096 316
+8752 10080 8355
+2098 12097 3672
+559 12098 12099
+2080 12100 8475
+12101 11631 12102
+12103 12104 11329
+12105 12106 12107
+12108 12109 11307
+8185 7900 12110
+5944 3787 12111
+8295 7693 12112
+2038 12113 9153
+12114 5263 12058
+12115 11817 6400
+7337 12116 2389
+12117 3629 12118
+12119 7674 12120
+12121 6823 12122
+11962 778 438
+5119 8349 9305
+11153 12123 12124
+5698 9801 12125
+12126 12127 12128
+12129 12130 12131
+476 9410 11199
+2253 12132 5899
+12133 11047 10020
+11585 3635 9759
+1722 10869 7507
+8071 12134 12135
+12136 12137 12138
+11263 10108 9909
+11465 7949 12139
+355 12140 930
+10001 3511 11279
+11520 4575 12141
+7500 12142 12143
+12144 12145 8664
+11677 7394 7076
+4330 12146 12147
+2763 5228 12148
+12149 8621 5279
+12150 12151 12152
+6928 4606 12153
+11195 7726 12154
+12155 1342 12156
+10028 12157 2793
+12158 11293 12159
+12160 1092 11644
+12161 12162 12163
+12164 10196 9172
+9252 5285 12165
+12166 11302 2989
+2457 7213 10142
+12167 12168 7166
+9425 9280 3908
+2707 6635 8118
+10467 12169 3739
+12170 12171 5272
+12172 12173 7227
+1104 12174 10224
+12175 12176 12177
+12178 6095 4196
+12179 12180 104
+5624 12181 9995
+10493 7727 3418
+10132 8240 10103
+2427 12182 4430
+11593 243 12183
+5895 12184 12185
+12186 6948 12187
+12188 262 738
+10245 6941 9951
+2157 9362 12189
+12190 8756 12191
+11049 12192 9997
+12193 12194 7732
+12195 10549 12196
+12197 175 12198
+9266 12199 5630
+5519 3354 12200
+2122 12201 11399
+4681 12202 10913
+6193 9535 630
+12203 8993 10313
+7997 612 834
+9099 8064 12204
+2335 11505 11851
+12205 12206 7862
+10607 12207 12208
+12209 4754 12065
+3577 3330 12210
+12211 67 9777
+9538 2986 4507
+12212 12213 1411
+12214 10739 12006
+8710 12215 12216
+8922 8634 18
+11679 12138 12217
+12218 9841 9338
+8882 5637 12219
+7804 12220 6452
+11894 12221 5803
+411 1510 12167
+10354 12222 6272
+12223 12224 12225
+7096 12226 12227
+6990 215 12228
+12229 12230 9184
+12231 9139 12232
+12233 12234 7486
+1391 7118 11255
+9335 9548 7410
+10213 12235 12236
+12237 11843 6385
+12238 12239 2402
+11333 11077 4993
+7678 2769 12240
+12241 12242 11381
+12243 4990 12244
+12245 12246 12247
+10631 10007 10875
+7517 6322 7713
+10395 1001 3514
+9749 12084 10004
+102 12248 12249
+417 11175 9885
+11239 6173 12250
+7735 8192 12251
+1254 7186 1564
+12252 10714 4649
+12253 12254 12255
+8169 5252 9940
+10902 7777 11581
+12095 9704 9230
+12256 12257 1965
+3192 12059 2192
+1726 1619 10018
+6477 12258 9912
+552 565 4184
+11158 1991 12259
+9037 12260 12261
+2754 492 12262
+12263 12264 12265
+12266 10215 9918
+1828 9318 4439
+12267 110 12268
+12269 12132 9725
+984 12270 12271
+10285 12206 118
+12272 496 6282
+7556 12273 4776
+12274 353 12275
+1298 12276 10302
+10174 6617 12277
+12278 9697 10747
+6511 10831 9509
+11467 12279 7887
+12280 3401 3218
+12281 10290 12282
+12283 12094 9848
+11477 4814 6963
+12284 11780 10430
+12285 5665 3015
+10627 6797 50
+1372 12286 12287
+12288 8869 8649
+9974 4700 6545
+12289 9991 12290
+6129 12291 12292
+10893 11510 8950
+12293 12126 12294
+6968 12295 12296
+12297 12298 12299
+9304 5888 3701
+12300 8530 7322
+3633 9289 3206
+12301 1993 11495
+12302 12303 12304
+11964 9610 12305
+12306 5480 12307
+12308 12309 12310
+3052 9375 12311
+12312 12313 12314
+4557 12315 641
+7475 4182 1509
+12316 12317 12318
+6299 11306 9240
+12319 12320 12321
+9566 12322 12323
+6430 12324 2633
+12325 8263 12326
+11527 11269 12327
+8463 2123 12328
+5591 10937 12329
+4186 881 12330
+12331 12332 1696
+11453 12333 3791
+3777 1879 3412
+7985 1939 6922
+6524 448 12334
+2333 5586 12335
+9528 8923 11450
+4719 12336 12337
+11319 12338 12339
+1691 12340 4052
+6699 8529 12341
+6561 12342 10258
+12343 12344 11219
+12345 11642 11551
+416 4888 444
+12346 11863 8191
+372 8958 12347
+12139 10873 2257
+12348 2587 7395
+1743 12349 12350
+12351 12352 11500
+4670 4871 2584
+12353 12354 12355
+12356 12357 12358
+12359 12360 7813
+6077 4516 12060
+9036 10734 12361
+5368 4257 12305
+12362 12363 12364
+12365 6645 12366
+5113 12367 8437
+10203 6537 12368
+11875 12369 12370
+3880 12371 3858
+12372 12373 12374
+5869 6052 12375
+12376 12377 12378
+8912 11999 8282
+12379 11564 12380
+12381 12382 4
+2056 12383 8449
+7204 11575 12384
+12385 2317 12386
+9373 8615 10305
+8565 12387 12388
+4022 12389 706
+12390 6932 9721
+12391 5997 12392
+7485 8374 5710
+12393 12394 1022
+8596 4431 12395
+12396 9851 5346
+12397 12398 12399
+2932 9175 12400
+12401 7066 12402
+12186 2322 11196
+2147 11545 12403
+12404 12405 12406
+12407 12408 8196
+12409 5429 5103
+12410 12411 12407
+12412 7814 6618
+1256 4929 11587
+7032 3004 10230
+4291 1867 4782
+10460 3792 12413
+2935 12273 11900
+12414 12415 10030
+9872 12416 3361
+9676 12417 11937
+1174 12418 12419
+40 12420 12421
+12422 12423 8146
+10477 12424 1456
+1959 12425 12426
+10435 10814 12427
+3310 2591 1181
+10645 12428 12429
+3522 12430 10568
+5554 9339 12431
+6219 12432 3337
+12433 12434 1798
+1568 5687 12435
+12436 1326 11149
+4999 12437 12438
+12439 12440 2493
+12441 12442 10295
+12443 5726 12444
+12445 7307 12446
+5512 11891 11688
+1099 12447 5734
+12448 12185 8358
+661 12449 7208
+9905 12450 45
+7589 6235 10372
+181 5001 12451
+10021 12157 8815
+11019 12452 3386
+8562 3368 7930
+9730 10861 12453
+363 3610 3208
+11876 2626 7387
+12454 7494 12455
+12456 7153 12457
+1397 12458 6181
+11470 12325 12459
+8248 11991 2990
+9116 12460 12461
+12462 8341 4688
+9525 11166 12463
+8254 4850 12464
+12465 12466 7523
+12467 9835 12468
+12469 12470 2736
+1885 7957 2517
+12471 12472 11538
+11791 454 12372
+12473 12474 741
+2983 12475 12476
+6906 10538 12477
+12478 1362 10723
+3139 12479 12480
+5742 9322 10297
+8829 8579 7776
+12481 12482 8934
+507 12483 1292
+12484 4672 4691
+12485 10851 12486
+12487 158 6940
+9735 12488 10769
+9095 12489 10306
+3120 7514 871
+11591 12490 12491
+12492 12493 12494
+12495 2000 12496
+10619 12497 3560
+12498 12499 12500
+11036 12501 12502
+12503 12504 3393
+12505 9308 12506
+12507 12508 5303
+7774 5894 12509
+7773 12113 12510
+11039 12511 3502
+5514 12512 1187
+12513 986 12514
+702 12515 10920
+12516 10828 4570
+12342 12517 10063
+6846 1933 7102
+199 2425 12518
+6814 7983 7331
+894 12519 12520
+12521 11392 2846
+12522 11812 12523
+12524 6356 543
+10355 12525 8782
+12013 9166 12526
+11647 12098 12527
+5605 11832 11253
+12528 12529 12530
+8679 10173 5457
+8372 10593 8600
+12531 12532 2647
+2323 5764 12533
+12534 9157 6688
+3941 6802 10136
+1857 12535 1719
+3067 12474 12536
+9935 3292 7650
+7817 8067 3620
+12045 9640 6144
+12520 5111 9924
+1546 12537 12491
+9454 9677 12538
+12539 12540 12541
+12079 883 1943
+12542 4362 5807
+8982 12543 9137
+6594 12544 11804
+3857 7832 12545
+12546 12547 12452
+4726 10976 12548
+12549 12550 7490
+12551 9775 1248
+12552 10074 4887
+11296 12553 12554
+12555 12556 12557
+7665 12558 12559
+12560 9904 11055
+12561 12560 12562
+12074 3458 12563
+9628 3727 7210
+1149 3624 12564
+12177 12565 11674
+2376 12566 12567
+12568 12569 2521
+12570 12571 12572
+12573 6406 12574
+12575 4344 9990
+11800 4658 10980
+6462 10176 12576
+9197 10536 11030
+12577 12578 12579
+12476 12580 4998
+7177 3407 10930
+12581 12582 12583
+11393 12584 2841
+12585 12586 12587
+696 2118 3888
+12055 7794 12588
+8110 7782 5987
+4771 12589 5500
+12590 12591 3101
+2618 12592 1795
+8943 12593 1553
+12594 4045 5623
+10770 12595 2375
+6860 12596 12597
+8326 12598 449
+4971 6168 12599
+12600 10270 12601
+12602 10670 10882
+12603 12604 11658
+12605 12606 12607
+12608 12609 9420
+11228 12610 12245
+12611 12612 7384
+3782 5891 12613
+12614 5640 12396
+12233 7528 12615
+12616 3964 12617
+12618 12619 1287
+3754 12620 5854
+12621 12622 12623
+12313 10812 10444
+1569 12624 12625
+12626 12627 12108
+10040 12628 12629
+12630 8070 6874
+12631 4006 112
+4064 2602 12632
+10539 11499 4050
+12633 11159 3702
+10168 3528 3246
+12634 6798 2195
+1718 12635 1856
+12636 11335 12637
+8778 5691 6429
+6298 520 12638
+3334 6641 12639
+11144 12640 12641
+12642 12643 7968
+5194 10594 12644
+10441 12344 1314
+12645 10002 1530
+8694 7462 4858
+10667 12646 12647
+11922 164 5920
+12648 9051 8394
+12649 11089 6432
+12650 3903 11833
+5703 9900 12148
+12554 11896 1407
+8902 4085 12651
+12652 10744 3267
+5034 12653 10459
+369 7509 12654
+818 12655 12656
+12657 6659 12482
+12658 12659 8851
+5134 3468 11698
+1442 7680 8651
+4485 12660 12661
+8400 3659 2629
+8458 12662 12663
+12664 12665 12666
+12261 12667 1772
+12616 1872 7660
+1297 12668 4924
+11773 11978 11842
+4380 12669 12218
+6151 2413 12670
+12671 12672 8844
+7981 10924 12673
+2933 6153 12674
+4951 1830 11458
+8917 10035 11090
+12675 9746 12136
+12676 11118 12677
+12678 12679 12680
+12681 12376 10666
+8695 12682 11367
+6609 12683 4772
+1450 12684 12036
+12685 12686 1233
+12687 12688 4340
+12689 3585 1050
+5800 8170 6502
+12690 2481 12691
+242 8388 9882
+5511 10710 12692
+3684 12693 12573
+11943 963 9029
+11570 8976 11771
+1902 11190 12694
+11471 6507 12695
+9494 11893 3341
+12696 12388 12697
+12698 1539 3907
+4433 12699 11327
+10977 9796 12700
+931 4740 8667
+11521 10042 2417
+1780 12701 12702
+5387 12703 7567
+6907 8794 6016
+7637 12704 11369
+12705 2062 12706
+6622 3675 12707
+12708 885 3164
+12709 12710 12711
+12712 6724 12713
+6784 4183 12714
+311 6748 5627
+9996 9818 9854
+12715 10562 4773
+5584 8300 8456
+12716 12717 12718
+11420 7417 10164
+10597 6493 6889
+12673 12719 4127
+12720 4205 10321
+12721 12722 9489
+12723 1898 9244
+11819 12724 12725
+1970 12535 8506
+11468 519 12726
+11143 10086 12727
+9090 10446 3404
+12728 1960 10300
+12729 9229 9982
+9226 12730 12731
+7841 12340 9009
+12732 12574 6531
+11374 12733 12734
+12145 6563 12735
+5871 3892 1919
+12736 11700 7596
+12485 1432 8030
+1763 4667 12737
+4219 7259 12738
+11508 12739 10652
+12740 6313 11652
+4856 1196 5755
+4111 12741 9050
+7515 12742 6863
+5419 12743 720
+12744 3781 3950
+9635 12745 11926
+12746 12747 10186
+10093 4758 11102
+9092 12748 8586
+891 2759 9617
+8730 1646 4094
+12749 3045 2786
+5575 1490 12750
+6391 12751 12752
+12753 9164 9461
+12754 3819 7444
+12755 12756 5106
+4683 2466 12757
+7964 5705 8724
+12758 12759 10802
+12760 7623 12761
+12762 10087 9282
+12763 12363 3720
+11706 12764 12765
+141 10017 12766
+12686 5100 12626
+12767 6449 12303
+8684 11341 12374
+9702 12768 10197
+4592 12769 12770
+4117 12771 12772
+792 2882 899
+12466 12773 11503
+12049 10732 4221
+12774 6745 1389
+283 4214 3716
+6605 3098 198
+3817 12775 775
+747 12776 12777
+12778 12066 5175
+12402 9005 11265
+7074 12779 12780
+5489 12781 12782
+12783 9138 1121
+12708 12784 1944
+12785 8936 2321
+9274 12786 12787
+3884 7378 12788
+6031 8188 12789
+7447 12790 5718
+12791 9202 4432
+11588 12122 11249
+12792 12793 11423
+10292 12794 217
+11906 182 11512
+12795 3140 3038
+12796 3839 12797
+12057 11514 11161
+4313 12798 12799
+1047 12135 11409
+9460 4255 1139
+12800 4378 12783
+4836 10931 9433
+9653 6111 7872
+12801 11757 12802
+12803 10547 698
+3970 7631 7902
+12804 8270 8611
+9952 233 12805
+12806 12807 12808
+10877 12809 9234
+6903 5873 7610
+5439 10653 8422
+11309 12810 12811
+12812 12813 12180
+2982 11874 12105
+9984 12814 4180
+8760 6233 3179
+9439 2525 12815
+2431 12816 12817
+12818 2501 12166
+5076 6866 8598
+4891 12171 7952
+12819 12820 531
+8446 8875 11017
+7185 10322 12202
+12821 12822 6969
+12823 11357 12426
+12824 11574 10974
+4811 12825 1462
+10706 5102 8607
+4096 6127 6943
+11011 12826 8703
+12827 9718 12828
+12829 12830 12831
+6427 3383 3233
+8269 12832 12833
+12834 2050 6509
+12835 12836 1504
+332 798 12837
+5632 12838 2907
+12839 957 10996
+782 11648 12463
+959 9855 1426
+12840 6350 2359
+12841 6912 12842
+12620 10965 12843
+11430 12844 9810
+2509 12845 3815
+12846 9546 10777
+12847 6551 12423
+12848 4054 1984
+1870 5799 11848
+8688 12849 7354
+5463 12850 2912
+7916 12421 11711
+7113 12851 12852
+2646 6603 197
+12853 12854 4766
+11449 6161 12855
+3181 12856 10531
+11940 9665 10419
+10370 11236 12857
+6232 12858 11720
+12859 12860 8983
+12861 5392 12862
+7000 183 770
+11343 5408 12863
+12298 2484 1844
+12003 10933 12861
+12679 12864 12865
+12866 7926 6212
+5824 6879 2758
+12867 7440 11626
+9082 4390 12868
+7078 2558 992
+1135 7081 2030
+7349 12869 6501
+11032 8069 12870
+10520 8100 5790
+12871 6861 12872
+7152 12414 12873
+12567 12874 10412
+2812 6305 12875
+12876 6577 12877
+4425 1764 1158
+6888 12878 6491
+12879 8027 12880
+9481 9809 12881
+11918 1188 4327
+4770 12882 12883
+12884 12885 12886
+12887 610 12888
+12889 3915 12890
+2817 12891 3636
+12892 12893 6735
+12379 10362 1283
+1355 12894 10369
+11733 12394 6763
+9422 12895 12896
+10089 12897 12898
+12899 12900 8872
+12901 9471 12351
+12902 12903 10963
+383 11080 9669
+2075 6297 11231
+4716 10641 10953
+11957 11310 2854
+8878 5635 7145
+12904 4633 3014
+11907 5465 12905
+6471 11133 4331
+12906 12907 12908
+9626 2504 12909
+10118 8359 12910
+9758 9131 12911
+12912 12913 1226
+4541 12659 10989
+12350 9595 12033
+12914 12442 7363
+12172 12915 12443
+10866 12916 6420
+6964 8180 75
+12917 5288 9436
+2002 12918 12919
+669 12920 8981
+5355 9091 7568
+5543 1183 11630
+10318 12921 10217
+12922 12923 12924
+7836 5815 12241
+8500 12925 7544
+7365 12926 12903
+10515 12927 12928
+12929 12918 11142
+4523 11536 12101
+12930 10326 12931
+3399 7973 1489
+12932 12102 5242
+4041 7731 6416
+5028 12860 3834
+5786 10567 12933
+9110 12934 11284
+1492 12935 65
+8915 8066 12021
+4141 2760 890
+9685 12936 12937
+4360 12938 12939
+7318 12940 2237
+10755 7483 12306
+10212 12001 11766
+1908 11243 3588
+12941 7087 2523
+6355 8826 12548
+12942 5948 12943
+340 8264 12944
+12945 12946 12947
+5878 5860 10357
+11257 12948 960
+10708 1444 1029
+304 12949 12950
+5137 5638 8861
+9313 7719 4831
+6415 12951 6304
+5905 12952 3794
+12953 9444 2811
+4174 7306 12438
+8584 12954 10661
+3665 10798 3547
+10067 1878 5791
+11289 12955 12956
+10999 12279 12957
+2886 12896 12958
+12959 5563 12103
+12960 12961 11139
+1628 12962 12424
+9843 12963 9616
+2385 12655 9188
+12964 12965 12966
+12967 3862 12968
+7903 7020 12969
+9606 12555 11945
+5768 11350 12178
+12970 11578 12971
+10621 8927 10219
+4455 11542 5901
+7811 7753 2131
+12972 12927 12973
+12151 3350 12974
+4247 11365 776
+9570 12940 124
+12975 1900 5947
+12976 12977 7151
+9925 2930 12149
+12978 10945 3091
+6401 11294 12979
+12980 12981 8539
+10818 12982 12983
+12984 12985 12986
+10527 8940 1921
+11358 12987 4131
+11840 7505 3105
+4405 12525 12988
+12989 12990 5044
+7917 12276 2887
+4048 12991 5217
+9706 12441 11865
+12992 12993 5760
+12994 12995 12996
+4400 8969 1499
+2589 5968 7396
+12997 1476 12749
+2236 12998 7992
+5866 9382 3289
+11390 9023 12999
+13000 10748 13001
+12187 13002 5765
+9223 2951 11079
+12640 7449 13003
+3748 13004 12645
+6100 10650 13005
+3491 13006 7554
+3457 13007 735
+7154 4037 9483
+11954 8819 8277
+7607 613 3062
+3507 12257 13008
+9478 11258 10119
+9791 5380 13009
+7467 12683 13010
+7695 4651 9239
+13011 10847 10970
+7488 13012 11033
+10423 6225 13013
+13014 12774 13015
+8626 6580 1946
+13016 13017 12794
+13018 12660 2605
+13019 12619 13020
+11793 3853 10610
+12558 13021 4471
+6689 12071 8165
+3363 2668 9152
+13022 2139 13023
+2865 11908 13024
+11886 11672 11063
+1390 13025 8914
+13026 13027 13028
+12400 4624 5246
+8701 686 10948
+11478 12508 6446
+6113 344 13029
+13030 3775 3345
+13031 1705 2687
+13032 11748 7978
+13033 4339 13034
+8772 10367 13035
+4034 2049 9354
+952 4643 13036
+2806 13037 13038
+9879 4027 12590
+8670 10384 7612
+578 13027 58
+11446 1640 3949
+13039 1580 12935
+7532 13040 12904
+13041 6552 13042
+13043 12244 13044
+5329 13045 7165
+13046 13047 1394
+9426 13048 3447
+12014 11837 2573
+13049 9965 12502
+12840 13050 13051
+12016 4098 12880
+13052 5358 11068
+6480 1709 5811
+13053 13054 13055
+13030 13056 13057
+13010 724 13058
+1424 3057 13059
+11977 6512 3707
+13060 653 13061
+8929 9553 13062
+13063 9465 13064
+11634 13065 9849
+8144 7685 3080
+5680 2712 2822
+11895 10564 9662
+10462 11715 13066
+12208 13067 11959
+6876 13068 13069
+2463 12990 9684
+8663 5192 9963
+3758 13070 3284
+10335 12630 13071
+6324 13072 10623
+11743 13073 108
+8728 11035 7915
+13074 1290 9031
+174 13075 8181
+12477 13076 4119
+13077 10014 4410
+6613 13078 13079
+13080 13081 13082
+3582 1866 13083
+2119 13084 13085
+13086 5047 8697
+10832 7632 12243
+10580 404 5105
+13087 13088 13089
+13090 4397 9078
+13091 13092 5505
+231 13093 13094
+8763 13095 12338
+13096 13097 6833
+8979 12916 13098
+1903 5058 4996
+12051 13099 1153
+10806 13100 13101
+12500 2133 13102
+12064 13103 5382
+10453 13104 13105
+13106 4530 13107
+11078 13108 8433
+9112 3548 2269
+13109 13110 10960
+9949 10811 13111
+1590 10084 13112
+13069 8342 13071
+13113 8997 1454
+13114 13115 7984
+13116 3639 10484
+2491 9723 11544
+13117 11995 10618
+9881 13118 13119
+12343 475 1975
+12802 186 5995
+7236 11701 12283
+13120 7027 7183
+13121 6160 8573
+12986 7474 10181
+13122 13123 13070
+9651 2996 13124
+13125 12895 13126
+8058 3476 7527
+13127 11311 5156
+12911 6897 3280
+763 8731 12761
+3709 5552 943
+2442 1436 6824
+9636 2437 166
+6134 1051 13128
+13129 3590 10166
+13130 6236 2001
+4933 8323 5485
+10796 9737 13131
+10638 1840 7876
+13132 12731 13133
+3058 3257 12165
+13134 5085 4482
+13135 924 6868
+13136 1128 13020
+7676 12936 13137
+13138 3154 614
+13139 13140 10358
+2328 8432 3115
+5810 8517 2216
+13141 6329 13142
+9405 9999 13039
+12155 13143 629
+13144 13145 13146
+8398 13147 7146
+12294 12264 13148
+13149 13150 13151
+13152 11221 12992
+13022 261 12872
+9148 8857 12162
+12796 6565 11655
+13153 11361 8096
+6434 11429 12647
+12691 13154 7082
+10695 13155 10544
+13029 1354 2655
+13156 12981 3721
+538 12968 3481
+1410 13157 13158
+10886 5516 13159
+13021 11690 13160
+10432 12309 1594
+7068 11916 7793
+13122 2127 12754
+3558 9428 13161
+2462 13162 8856
+10378 10969 7167
+8938 5832 12528
+13114 13163 13164
+12629 6146 13165
+9458 13166 5782
+12837 8402 13167
+4235 12544 3899
+13168 11223 10718
+6576 9930 4678
+13169 7273 422
+13170 11052 3030
+8005 8847 12566
+13171 13172 12041
+9530 9033 2802
+8178 8966 12238
+10145 13173 5160
+13174 12137 7058
+9165 5013 7415
+5342 4177 8053
+11612 13100 13175
+11822 12938 13176
+4025 11790 12750
+5618 12011 13104
+7127 4912 13177
+1678 7042 4479
+13178 12259 193
+10928 13179 11754
+9287 12816 12570
+10688 13180 13181
+9097 13182 13183
+12937 13184 13185
+13186 13187 1300
+3027 11363 6384
+10994 872 11921
+12879 12224 2070
+13188 8172 13189
+13190 12868 6107
+3351 13191 6992
+3978 3124 13192
+214 3863 1305
+7797 13193 3331
+9915 1401 10210
+5517 13194 8195
+10919 11883 13148
+13195 6188 13196
+11920 2182 13197
+8866 5016 7714
+13198 11058 13199
+1928 10719 12832
+4502 10175 13200
+10575 8084 7397
+12958 11869 13201
+11712 271 9674
+12947 2543 4907
+11735 3054 7364
+7588 13202 13203
+13204 3537 3066
+13205 5188 11815
+6587 1506 3512
+121 9522 10183
+6557 2697 2805
+12905 13206 13207
+13208 13209 12281
+1109 486 13210
+12271 13163 6813
+1605 13211 5114
+5701 13212 13213
+11497 3269 13214
+13215 4367 13216
+9752 12387 11194
+3741 13217 11970
+1098 10624 11665
+4669 13218 8104
+8453 5435 7705
+7880 9381 7671
+2432 11559 11909
+8383 9281 3981
+6960 4708 847
+11901 13090 13219
+1433 12215 11038
+5165 2205 6835
+6682 13220 5943
+13221 2564 9413
+7482 11857 13096
+722 13222 1152
+12432 6217 13223
+13224 8835 12272
+1716 13225 3531
+13226 13227 6718
+13228 129 9880
+13229 3321 13230
+10551 11983 8951
+13231 6760 7543
+13221 12596 5291
+13232 11473 10849
+13233 1232 1576
+13234 11649 13235
+3099 9671 5628
+13236 5745 13237
+13238 13239 7436
+10310 13240 10359
+13241 9637 168
+3396 9983 8785
+12227 7129 10554
+12766 2145 10600
+1521 12267 8120
+7223 7346 9826
+1138 13242 3979
+7282 8818 8795
+5672 7853 13243
+10050 11928 13244
+8461 6836 13245
+13246 12209 6627
+12384 6358 13169
+13247 6353 13248
+5299 12450 13249
+2245 13250 13251
+1998 12926 8230
+4449 13252 13253
+12972 13057 13254
+11797 6610 3241
+9258 13209 13255
+13001 2765 13256
+13257 958 11297
+2477 820 12160
+11461 8759 8006
+7313 13258 8033
+4905 12062 5979
+9312 13259 11561
+13260 4147 13261
+13262 4777 2934
+11437 12726 11663
+3200 7827 6714
+11621 9981 7663
+13263 3960 11046
+13264 13265 1465
+13266 13267 11755
+4150 12999 12190
+12356 13268 6242
+12909 13118 604
+12009 2650 9386
+5461 13269 13270
+6058 7506 13271
+8219 12516 12321
+8858 12299 13272
+138 4529 13273
+12605 13274 8021
+13275 12617 6176
+13276 3248 8380
+10705 4484 6022
+12431 6929 944
+13277 13278 878
+1273 11948 7907
+9466 13279 9675
+11984 13280 6386
+12287 867 12381
+10932 8860 4861
+13281 7426 12328
+13282 13283 361
+13284 13285 10909
+13286 7080 1367
+9804 1485 13287
+3851 13288 4653
+10391 13081 13289
+6623 11760 12983
+5336 2243 10867
+10070 10341 11762
+6319 10762 7601
+740 6027 11119
+4722 5483 13290
+2008 11759 11313
+9156 2134 13291
+13292 4355 11087
+9975 11976 12153
+13293 8407 2146
+8764 6290 13258
+8817 9584 13294
+8988 13295 11597
+1108 13296 2730
+4409 1244 13297
+13298 5708 13299
+5850 12495 13300
+11057 12745 8162
+13301 9921 9856
+9275 4978 2474
+13302 5324 10495
+2568 13140 2288
+1766 5068 13303
+6381 5233 9792
+13304 11237 12894
+11059 13305 13306
+12486 9464 12216
+13146 7360 4674
+11951 4630 11517
+13307 13095 8019
+9209 13308 8948
+8630 4765 13309
+66 2314 5981
+13310 13311 10317
+13264 9787 10508
+12639 8741 13312
+12526 9193 9237
+8863 5349 10220
+12161 5498 11531
+13313 13314 8412
+5732 6271 12081
+5383 12080 9609
+10922 13315 13106
+1794 13316 12692
+13317 13318 12672
+3837 4084 12513
+12496 3889 4278
+11691 13319 13320
+6684 4639 7855
+13321 5629 6458
+6790 7857 7998
+4155 13322 13143
+9693 273 13323
+12559 13324 13325
+13326 13026 13327
+608 10644 13328
+13329 13330 3104
+11910 10234 13331
+13177 791 3176
+13332 13333 9762
+13334 2634 9681
+3670 9417 13335
+10009 2181 7844
+12561 12747 4154
+11444 13336 3397
+13337 10659 12715
+6343 7555 5493
+12969 13338 10148
+12369 5839 11334
+7458 7377 11547
+5421 13339 480
+13340 6402 4725
+11747 2868 3203
+2836 7606 12661
+13341 545 7963
+9700 13342 13301
+1762 9552 4648
+12563 11838 8026
+13343 13344 13345
+4974 206 13346
+6179 317 13347
+13244 4855 9366
+1191 2764 10236
+2567 10232 13348
+13349 4785 13350
+4769 9270 9694
+11115 9215 13351
+13352 11204 12633
+7162 5951 2459
+6890 8660 679
+4664 8303 13353
+13354 9579 12220
+13355 7696 6788
+12545 11000 13356
+13357 9132 13358
+13359 13360 12956
+12930 12296 9517
+7824 13361 8223
+4492 7558 13362
+8044 12952 11656
+8871 13363 4143
+11207 10746 8113
+13364 12982 13365
+11899 13366 10109
+8893 13367 9056
+5066 13368 12931
+9824 9547 5785
+10716 11974 13369
+8132 11154 10742
+2130 980 3893
+3451 13370 13371
+1805 9978 8908
+8426 10682 11518
+12255 6023 13372
+2109 13373 7689
+13374 13161 13375
+10800 11923 7119
+7990 11320 11455
+11786 8790 13355
+1482 6403 4518
+6260 9506 11042
+13376 3346 13377
+1368 7343 7199
+4388 13378 11867
+13379 8827 954
+11935 11678 10102
+13380 155 9263
+13381 11611 11026
+11763 1347 13382
+13176 13383 11820
+13384 13385 13386
+13064 10850 12073
+13387 10208 13388
+13389 12449 10860
+3811 13390 13391
+13392 9174 12087
+12552 11713 12198
+2919 2641 13393
+3842 7819 3555
+13394 11552 13395
+5088 12934 11388
+12670 3389 13396
+12120 11569 11844
+13397 13398 13399
+13400 11001 13179
+2740 1295 11769
+1472 7258 13401
+9695 12032 3841
+11758 13402 13127
+4031 13403 4957
+9977 5443 7135
+13404 11752 10324
+1348 10340 10123
+11091 145 8076
+8261 13405 7392
+13406 13407 12650
+7762 13184 1163
+484 13408 7456
+8550 3300 8839
+13409 4014 11992
+8855 13410 160
+11439 13411 10957
+13412 10407 8124
+6989 3988 9798
+7207 440 11839
+2710 6357 13413
+12509 10816 8125
+11251 11880 13414
+8322 13415 11148
+10874 13416 5936
+4324 2795 13417
+9253 7190 10985
+5413 13418 13419
+13420 13348 13345
+4867 1045 1520
+13421 6049 10463
+7065 12332 4747
+4807 6247 9440
+12150 8397 12456
+6199 6980 13422
+6211 13423 12385
+12689 13424 13425
+12022 13426 6249
+9133 3260 6898
+13427 9067 3750
+6983 13428 2099
+13429 13430 13049
+13431 8385 4865
+517 7879 5582
+2784 6055 13432
+6276 1880 7988
+10958 12780 12469
+2183 5244 12795
+3180 11722 13067
+6140 1049 13433
+284 9615 13256
+13434 13435 9192
+3093 13436 4191
+13437 9393 13438
+11778 12026 13439
+6437 13440 9592
+13441 2028 8462
+13442 9831 5945
+13327 11741 9388
+12451 13443 11513
+8085 13444 13445
+10456 9199 1784
+11165 5851 7255
+10774 2024 13013
+13446 13447 8569
+13448 5157 4018
+13449 9860 10753
+13450 9346 11967
+4729 1134 10056
+13011 1700 13451
+6761 13249 921
+13452 10939 7869
+9896 4193 7779
+7056 10120 10106
+187 13453 5715
+13347 7959 13454
+9269 13455 13224
+13456 5000 1356
+759 1702 12614
+13368 5958 6966
+11085 5654 11081
+12085 4353 151
+13457 10149 4565
+9515 12336 13458
+12251 4607 13459
+13460 13461 13074
+10486 10339 4319
+12581 10031 7200
+13462 13463 13464
+13465 13466 1137
+13340 13467 10263
+10674 10303 4601
+5789 6278 13468
+5744 7787 13153
+10887 10398 13194
+13469 8119 6961
+12070 11160 13376
+12140 9222 4738
+13470 3698 13471
+7433 298 11197
+13472 13473 13474
+4137 5208 13461
+11067 4459 10327
+13475 2531 13476
+13454 11298 13477
+3416 2597 13478
+9437 8939 12712
+13479 8423 12739
+1565 12874 6286
+1461 12383 10736
+3878 10532 13178
+13480 5327 6254
+7158 3425 13481
+11193 9379 13482
+11987 13155 11347
+11226 12254 13483
+13484 13485 810
+13486 13180 10363
+8324 6523 13342
+4138 10044 13487
+467 13488 10759
+13207 10034 13091
+13489 4413 13490
+4611 12989 13491
+8842 5510 13299
+968 13453 12677
+13492 13297 4222
+12169 11261 13493
+13494 11601 6190
+8610 4801 5604
+13495 11836 8738
+2978 6048 11798
+6167 1589 875
+13496 6418 6421
+9360 8953 8821
+7666 13497 13498
+2810 13499 5423
+8955 10023 13500
+13275 7829 4967
+13501 13502 13503
+9424 8538 6369
+13504 10256 8768
+981 9561 13505
+13506 13507 4164
+13508 12367 5532
+13509 13510 1096
+7960 13511 294
+13512 13513 13514
+7237 11515 13513
+6518 13438 582
+12853 546 683
+13515 13516 7790
+13036 12075 8820
+2148 13517 13518
+3943 13519 6747
+8676 13520 3963
+8415 4075 12576
+299 46 3810
+13521 9683 13522
+3075 13285 2297
+13523 13266 9498
+13524 4864 12551
+6363 13525 12039
+6572 7103 13526
+12392 13527 9741
+8242 13528 13529
+13530 11082 8513
+12158 13531 6690
+8259 13532 11396
+8183 13533 13005
+2476 8492 13534
+13535 12591 367
+9140 9190 1832
+1203 13536 6974
+8345 8888 11645
+2372 8302 10700
+996 10076 7107
+12728 13537 3127
+10852 13538 13539
+569 11860 12784
+13540 13541 7745
+12803 13542 12533
+7801 11053 13543
+1253 13331 13544
+107 2737 13545
+6250 11318 13546
+11266 4229 9093
+13547 8357 13548
+13549 13550 13551
+9072 7742 1782
+9343 12810 7831
+7336 13552 10138
+13553 10439 13554
+12275 11719 11853
+7083 13555 3711
+13556 13557 13558
+12975 2798 10503
+12315 7072 12839
+618 12007 7141
+13559 1647 5010
+6679 4058 9320
+13560 13107 9572
+4128 9493 13561
+12665 12875 1329
+13562 7030 13563
+13564 12288 7679
+13565 13566 8025
+13567 7004 13318
+13568 1663 3523
+13503 11447 9689
+13569 5445 3204
+8167 11640 13274
+3774 12239 13570
+11415 7340 12348
+7974 575 10524
+473 11641 1776
+11132 13488 2391
+12519 13571 11463
+5254 10157 13400
+2678 5069 13572
+13573 9520 5580
+13246 4462 12644
+421 515 7203
+1526 13574 7489
+13575 9181 13576
+9559 13577 13578
+13579 11360 2719
+11056 8753 11925
+13580 7751 12099
+6896 11924 13581
+8438 13015 5999
+13582 6347 2003
+13189 352 5006
+1641 7636 7874
+3934 5333 13583
+13584 11598 5375
+7253 10443 8970
+10951 8297 6871
+10526 2823 13585
+5301 13586 12741
+5357 13587 10447
+10323 11493 13043
+13588 1801 13589
+11198 4829 2877
+13023 8382 739
+7441 7125 8534
+13040 13590 12763
+13591 12855 13592
+8063 13593 12410
+12711 10655 8459
+463 9833 13594
+10193 2513 12018
+11519 13595 6884
+5879 13111 8978
+13596 6131 11270
+6812 3808 10129
+8595 4102 12791
+13597 11136 12893
+13598 893 4209
+10615 9123 12610
+8523 4042 13496
+13599 12684 2494
+3832 12776 13326
+11821 13017 13600
+12368 12720 13601
+12876 7226 13602
+11096 8288 3561
+13603 13604 6318
+8766 11562 10829
+2312 670 8620
+60 3187 13605
+595 11384 13032
+5467 6364 2550
+8482 2026 12505
+12888 326 13606
+13607 5473 12141
+10839 5793 2916
+13608 10766 2033
+5941 11990 13437
+13133 11308 8793
+4423 7182 13051
+13379 13609 11502
+10518 10713 12870
+11424 12242 13610
+13611 13467 13612
+7886 4382 12473
+4061 5032 6105
+13120 13136 13613
+4638 142 12959
+13614 225 13615
+13241 13512 11299
+13489 12871 6933
+7688 8364 3603
+3650 8182 13616
+12594 3347 9934
+3175 9434 10163
+13617 12005 12111
+6555 13618 5907
+13619 2724 2828
+13620 9059 2972
+13621 13622 8884
+13623 13624 13417
+13621 13187 10421
+13625 13626 13627
+13628 12746 11555
+7618 8377 13629
+13630 2217 11942
+13199 2814 13625
+12562 3413 10069
+10728 13452 13631
+8320 13632 8690
+9075 10730 11126
+9155 2948 7244
+13633 12852 13456
+8909 13634 1803
+13635 13636 13637
+1460 10152 13638
+12159 239 12247
+6014 13639 8049
+5574 9895 4941
+6207 12235 13640
+10738 3438 5326
+13641 11680 6550
+13642 11275 13643
+13443 12851 12397
+13644 24 13645
+13646 7995 1835
+2287 13192 209
+8393 12809 8116
+11704 2624 11484
+13647 4673 12078
+13573 914 13648
+11739 2199 7725
+13649 1402 13650
+10390 13651 12994
+13616 2603 12042
+13652 12835 6589
+6450 12031 4842
+8467 10139 4176
+9276 13330 11394
+13563 10229 12663
+9962 12517 12144
+10464 13578 10271
+6698 12854 11729
+6025 11651 6806
+5884 8074 1251
+9956 13653 6648
+11169 13083 13654
+8101 10870 11554
+13654 8508 7850
+7439 8536 140
+13655 802 13656
+10942 13657 10803
+13222 13411 13658
+9046 3930 9183
+12461 13659 10038
+13660 13661 6632
+2228 7682 348
+6665 10955 721
+6822 13662 7239
+13663 8376 13664
+13432 6917 13665
+13666 13608 9819
+171 1148 12129
+849 13399 13124
+11451 13667 7053
+13668 8289 11138
+7369 12878 13669
+13566 5391 3904
+12608 2701 13336
+12976 1945 11859
+11086 13670 5215
+9058 13671 13672
+7286 13673 9034
+13362 10805 3329
+4093 12286 12760
+3082 621 13632
+8740 11736 12484
+9769 7522 13674
+10599 7323 5938
+1732 2193 5262
+7720 10458 11624
+11167 8718 783
+12772 7295 13675
+13676 1421 4647
+1677 11092 13677
+13048 6444 13678
+13229 3153 9376
+13504 13679 1942
+1592 2653 2307
+13175 13680 426
+9369 10153 12409
+4610 12966 9682
+12293 11882 10047
+2909 9667 318
+4524 7015 4544
+5187 9470 11285
+5929 12131 6920
+5721 10651 12752
+4731 6258 12690
+5706 13681 1602
+12284 407 13682
+11122 11262 8520
+13683 356 11560
+10822 11772 13684
+1615 13536 248
+8675 9597 13685
+11620 13325 10675
+2479 9986 13686
+12358 6294 1162
+877 11696 9171
+9414 13687 6101
+13688 11528 9356
+9623 3765 246
+11020 13433 13689
+5496 4545 10114
+11565 10426 9583
+13690 4136 13009
+4299 12790 11145
+6407 7754 11950
+11234 6378 12723
+13691 13692 13693
+8278 7284 10312
+13694 13619 6850
+2151 13439 13371
+13695 201 11799
+11792 8015 4395
+4346 12134 12290
+11397 9127 8257
+6148 12734 8578
+12263 2388 3614
+8977 1609 2350
+386 10630 13696
+3219 13697 12077
+4232 200 3186
+13698 8960 8469
+4132 11904 3820
+7654 13699 7012
+11295 5008 3997
+13700 8455 8102
+9889 7090 13701
+3439 12565 6425
+9351 7106 272
+901 3545 4783
+13702 3699 10008
+13703 12704 11445
+12230 13630 11971
+9638 13220 13704
+7359 12221 13705
+13706 9114 12961
+7564 11522 13707
+13708 13709 13710
+2939 925 12017
+3622 3128 5205
+2833 12595 13711
+9811 4806 5476
+1155 13212 5227
+3049 9435 4280
+6093 10442 13712
+4679 13713 5727
+4921 13485 13714
+6629 7251 10657
+13715 5852 13232
+13716 13717 8870
+11695 13718 5970
+13183 12688 12652
+10062 9286 4837
+13469 846 9550
+13719 13720 13230
+12539 13721 13722
+8715 13723 12701
+8568 7214 11208
+12713 12127 9371
+7247 7996 632
+3071 12593 13537
+3898 13679 2303
+13724 13370 13725
+8916 11325 2717
+11878 9853 8091
+13087 7366 10782
+7010 11824 590
+7752 13726 9068
+13727 13643 12266
+10450 12949 7006
+13728 8221 13729
+5309 12109 12133
+9876 4434 3415
+13219 10545 10022
+3159 1694 10916
+5980 8236 8623
+13730 4540 13731
+757 7355 8638
+12699 13390 11879
+4795 4753 6774
+4190 10884 12978
+13732 7085 13733
+13734 6328 12643
+11443 9729 5513
+1101 13025 13519
+8813 8859 11643
+13735 4325 10595
+1446 7590 13498
+4914 11100 2883
+13736 756 6711
+13656 1899 8802
+1513 4655 13737
+11825 7046 13738
+6399 6202 1081
+13481 12948 13739
+10731 7319 8656
+13693 10105 10100
+10151 13740 4847
+11061 4480 7143
+11305 13741 10276
+3417 6389 9874
+10239 9000 9055
+9485 2259 13742
+105 12813 1464
+3303 10424 12335
+527 855 11524
+566 13055 7891
+13743 147 8465
+13427 9315 12628
+13243 13744 7037
+6180 13477 13745
+10712 13746 12768
+1642 9724 12440
+7424 13539 8115
+11403 2351 13747
+10504 8705 12687
+11714 2165 9350
+10500 6895 5048
+13277 9077 11481
+9027 13423 13748
+8287 2652 13749
+12446 13750 13751
+9441 5012 8284
+9430 5220 13752
+4751 3302 13753
+13754 13145 13755
+12511 13447 9409
+884 13756 13757
+4243 1881 13670
+13758 13759 10247
+8617 11776 5549
+9540 10556 13760
+13761 13004 11613
+13762 10235 5037
+2347 11903 10411
+12420 13745 7923
+10570 13763 13568
+12932 2185 4521
+13413 7303 13764
+7799 11434 13765
+13766 13575 11501
+5741 2985 10161
+9536 6857 8526
+13167 213 13767
+9081 12232 4377
+5659 13132 10566
+11827 768 10725
+13580 11646 7896
+13063 13768 10542
+1704 12943 5641
+13769 9232 13508
+8059 5711 13770
+9710 7279 13631
+13771 13772 8850
+7249 12002 13773
+13253 13774 12678
+13775 5390 12847
+13776 13597 320
+6064 12258 813
+6628 2791 4460
+13777 9331 10146
+13778 9292 13509
+13779 6591 5422
+2968 7686 6752
+13731 9332 3669
+9827 11969 10550
+13121 11592 13592
+1330 12951 13576
+12191 13407 13780
+218 13383 12542
+5452 8305 2689
+832 9574 1519
+12395 13781 9104
+11404 13718 5759
+13782 9608 1483
+13783 10269 10478
+13784 13785 4902
+7005 5029 6112
+12457 13786 13191
+8072 7406 12289
+13464 10475 10693
+5804 7361 13754
+6759 1243 13787
+13788 12798 7645
+13789 12925 4270
+2621 9511 204
+5697 2552 13790
+13791 10535 12764
+12380 13792 13486
+6423 3680 3182
+1834 13793 1119
+6395 8472 13794
+13795 13796 8652
+7667 2115 11191
+13298 13797 13798
+13799 13800 13801
+165 1449 13794
+3210 13802 10729
+11589 8197 12408
+13803 5971 11405
+7885 1848 5556
+12657 13804 2931
+10596 13624 9361
+12899 9235 8987
+11427 8232 7937
+11661 12043 10006
+7704 13805 3764
+681 7571 10598
+8524 12831 3682
+11456 188 7529
+13722 11375 1622
+13365 13806 5927
+9283 13806 10819
+13807 4955 3380
+13808 12897 9817
+8476 10581 13159
+13809 13810 10011
+9018 13792 11476
+4826 11462 13811
+8360 11282 4818
+6522 3821 9922
+640 10677 7710
+6769 13760 8155
+9299 13393 869
+4742 2274 7741
+12960 11211 13812
+2234 13813 10180
+4659 1980 5752
+10915 1268 13814
+6804 13815 13816
+9913 6066 13817
+560 11697 13818
+13574 12954 8430
+11607 6339 12460
+13751 7837 11383
+13819 4060 5049
+13414 10400 13820
+6558 12642 5007
+13821 12703 13809
+9443 9370 6584
+11229 665 11795
+13711 9177 1648
+13531 7039 335
+11140 3876 2976
+1122 8551 13822
+6208 13823 10523
+13824 10012 12603
+13825 11668 13826
+1077 13827 13828
+11292 13278 1428
+11387 13606 1668
+13747 13829 2418
+5207 8904 6398
+12196 13455 11120
+12737 9543 13062
+1577 7325 13830
+4987 3661 13831
+12662 13426 13562
+13401 2301 10185
+8673 13832 13833
+13834 13835 219
+3141 5124 10126
+11244 13836 7769
+1393 3583 13837
+13838 179 3077
+7206 5471 11960
+13788 13839 7358
+1357 4120 11556
+3308 8173 13003
+13840 13263 13841
+8083 9521 13784
+11567 8265 6227
+1630 2235 5416
+11013 11749 5046
+7478 5977 10413
+8555 10082 8919
+13369 7416 1263
+8973 13823 1103
+13613 12618 13842
+10658 971 400
+3836 33 6926
+13506 1276 13430
+13843 3450 6541
+11742 13028 13844
+10804 5121 12210
+5610 5474 13845
+12928 10991 863
+13846 13847 6803
+13673 3156 13848
+9545 13201 13735
+13776 5276 6567
+10862 13405 11472
+10891 12398 6630
+3761 9976 13849
+11615 13850 13251
+1741 12034 13851
+10622 12627 9807
+13641 13852 2421
+10576 9484 13853
+3102 13854 8065
+13855 3942 13856
+10801 11723 9074
+10043 7721 8050
+3877 6700 12671
+13857 12128 13858
+11324 10987 130
+9816 4764 12889
+12000 8796 9108
+6695 5108 7061
+6333 5897 4398
+11732 5376 13295
+12971 13859 10704
+13848 13860 2800
+4846 13861 13862
+1661 6900 3381
+13863 13864 7600
+6008 2924 13865
+13866 13867 4548
+12700 13774 11342
+1550 10572 10776
+9842 6500 3065
+12681 13868 12624
+240 5829 13869
+6142 13440 11549
+13164 13870 9744
+11216 10858 4950
+13869 4496 12046
+13871 4574 8014
+13872 2852 13688
+13873 12523 3294
+12104 4684 13874
+8765 7315 8018
+12579 12769 13138
+13875 7737 13203
+11965 11533 10385
+13680 13876 1831
+4798 12083 13877
+13109 10835 12762
+13878 6596 8811
+8557 3238 7692
+6222 4051 13879
+13000 5671 9931
+9178 12512 3312
+7281 12357 7979
+9349 6424 10975
+2366 13880 13669
+8496 2694 13623
+4227 12609 13881
+9109 12998 3993
+2420 6230 11681
+13024 4091 4293
+13882 2124 11277
+13883 85 10072
+13700 13725 13843
+11590 3263 9385
+10813 13296 5146
+13884 13885 3165
+12163 13162 11586
+5155 184 11756
+5969 9673 5101
+2266 9701 3769
+11550 12808 13886
+13887 11184 13888
+6018 12470 13889
+13890 7139 13255
+13079 9812 13891
+12444 13892 13893
+8709 9463 10541
+13894 6191 12061
+9690 13895 6499
+4812 10737 7526
+11185 10929 3529
+12953 12664 2551
+12323 13690 5775
+8009 9512 2620
+7591 11938 11572
+6664 13793 13896
+11108 13897 38
+13898 12179 13284
+13446 13587 8712
+10223 419 5464
+11625 13356 10808
+4029 13899 7625
+12262 727 6348
+10347 9631 12970
+4259 13126 6301
+13900 10935 4447
+675 7070 13451
+5781 4580 6306
+5362 10833 76
+13901 9080 3094
+13902 12547 12716
+4099 13903 13904
+13425 13905 13837
+13168 13906 13907
+13908 13909 11371
+598 13646 10522
+12012 3644 9612
+3 1511 11227
+7701 13910 13402
+551 7432 13911
+11829 13344 11123
+5238 8329 7254
+12788 7457 12068
+13912 11884 4862
+4640 13913 13841
+13914 11516 11944
+964 1400 10724
+8788 3694 11286
+96 13915 7582
+12175 9245 13170
+13341 10198 13916
+8024 9954 5050
+8205 10298 5961
+1535 11831 13917
+13901 7929 12231
+10482 10064 10128
+12076 13657 13918
+11885 1457 11670
+9564 8889 8672
+1161 13919 2083
+4104 3436 12467
+13920 503 13202
+1025 5226 12599
+11931 13921 11252
+11012 13101 13381
+7174 13332 7353
+2821 13147 2628
+12908 7435 13922
+8648 11278 2713
+5607 10715 13406
+9862 13923 1626
+11064 13403 5896
+13549 13353 13924
+2508 13511 12096
+13351 1632 13925
+9821 13926 7373
+5559 8079 6039
+8395 13586 13927
+13099 13059 9061
+1892 10896 8330
+7502 10188 6799
+2154 13852 10982
+3535 6251 7287
+13490 10973 12030
+13928 3207 4238
+9800 4465 94
+2511 10726 12811
+13521 5648 6157
+2728 13006 3931
+7472 13929 13787
+13930 12494 6489
+13235 4281 6435
+3983 12955 10786
+12143 1036 6978
+5248 1849 13931
+12378 13932 12492
+8589 11939 11094
+4274 13750 12362
+10809 4702 12514
+8351 13933 13934
+13894 8693 11539
+13935 13225 11010
+10090 10823 5350
+8163 13655 4358
+10647 10773 10968
+2961 13338 8504
+10268 8421 2560
+7569 13936 13871
+9150 5906 12297
+12735 8495 11873
+12349 13937 11073
+9639 12044 8404
+9845 12622 12419
+2069 13768 1600
+13471 11337 13938
+6519 8975 11775
+13645 13939 8957
+10191 10894 7530
+2807 9015 13618
+4172 9301 13384
+6158 5657 5788
+6035 1955 4295
+10376 12 11727
+12564 2276 10946
+13940 13941 6270
+6852 5213 6106
+12817 11808 13683
+8029 13942 6120
+10154 13943 1041
+13035 11941 13944
+9825 10241 4321
+8543 13945 8597
+5378 2677 12743
+13946 11746 5240
+9 2194 3008
+13947 10525 12541
+2714 13948 13949
+13950 13245 2204
+13708 13210 10469
+375 8134 3840
+8974 13054 13516
+13951 13134 8631
+7132 11245 13116
+10481 3800 13952
+13953 2987 9805
+11312 13910 13954
+6697 12119 12237
+12669 8186 4932
+13955 13684 8553
+1303 13956 11377
+13186 13328 11764
+13833 13957 13831
+11328 12667 13958
+11101 13959 13960
+8406 13961 9533
+8931 4298 13962
+10401 5150 13770
+2855 13082 6527
+12530 10409 1182
+13963 13964 4107
+11209 13965 13966
+5597 5038 11368
+13967 12324 2540
+13807 10308 3083
+4682 13877 4709
+13649 10095 12478
+13254 6568 10992
+8204 2211 13968
+6259 4817 4906
+13969 9125 6600
+6705 1085 2528
+1378 11238 13372
+13675 3095 13190
+13970 11823 13971
+5116 1118 10765
+13612 10565 11151
+11810 11805 8036
+13972 9563 13149
+1150 13658 11606
+9923 13973 5716
+13887 13974 8849
+13891 11506 10131
+13522 13975 11134
+6914 11127 13802
+12192 3664 13415
+13976 11813 6826
+10592 13977 379
+13952 12048 1205
+7275 10971 12346
+13978 4307 8114
+13228 13979 11858
+11210 11660 3253
+5522 10890 8151
+8283 13800 1907
+13980 6004 3486
+6821 13466 13981
+13982 12882 9696
+13603 8106 12705
+9204 10557 13555
+13983 13919 7675
+13984 13985 10643
+11290 3408 8547
+12924 12727 5709
+9117 10754 10879
+5621 13986 1947
+6581 11114 2741
+11686 11946 534
+13940 12447 13855
+13987 2613 11200
+10255 1214 1321
+13988 2787 1021
+5198 13989 8754
+12738 11887 11504
+9866 2482 6257
+7641 8903 453
+13990 2106 10351
+13991 6762 13480
+3464 7748 13992
+12326 13993 6331
+12025 3063 6024
+12341 7479 7672
+11346 13915 13394
+12841 4995 11811
+6880 5719 11098
+13570 8965 13377
+880 13994 13583
+8552 13995 749
+1491 10096 1528
+13996 13528 13922
+9908 13739 13569
+7765 5401 10422
+1556 6777 856
+13997 12804 9959
+5470 5568 11584
+1009 6467 12386
+13998 13999 3286
+10954 8907 432
+13986 14000 9261
+7986 14001 3855
+14002 6454 7635
+9268 11726 9141
+8098 13845 4406
+11731 11433 13635
+13732 1434 6707
+6956 6485 10066
+11675 1850 4903
+7909 11966 14003
+9586 12415 14004
+1635 11788 4938
+10918 9742 4822
+14005 666 6296
+11802 11669 2360
+8632 14006 11256
+13273 14007 10405
+13282 14008 13692
+11996 6351 9291
+13234 12646 13795
+277 2426 14009
+9032 1864 14010
+8784 8138 11254
+3473 10116 10947
+1559 12848 12740
+14011 14012 13980
+6795 13721 8275
+4441 3509 12366
+12195 3333 14013
+6807 212 14014
+6117 12282 6409
+12354 10140 13585
+6285 6585 6931
+10029 12987 8816
+13967 6841 9151
+12480 14015 264
+3033 10264 52
+9445 14016 9001
+4821 14017 10517
+13584 13765 7608
+2161 7877 13682
+10122 14018 13276
+10360 11441 13367
+14019 1166 10717
+12685 10683 14020
+11537 14021 4704
+4576 10349 257
+13790 12666 628
+11509 7224 10552
+14022 12146 10364
+13988 13903 12015
+11099 12751 3309
+13674 12939 13600
+3913 8353 9519
+10530 12625 13868
+4152 6873 16
+13738 12814 10857
+13305 11301 8368
+7512 14023 3735
+789 3562 13884
+6040 14024 8251
+11426 2370 14025
+13866 13113 14026
+5369 7592 13571
+14027 11395 1082
+13844 9203 14028
+10254 539 8032
+9567 5787 14029
+12606 14030 8686
+9524 6103 9531
+13397 1767 7616
+10537 7299 14031
+11380 11955 6332
+9698 13267 10237
+13391 9875 300
+14032 7468 14033
+334 512 12534
+6772 12405 7786
+10511 8545 13470
+13691 6556 11532
+10640 14021 7828
+13912 6751 4053
+10169 13269 2380
+14034 14035 4857
+14036 8661 5145
+13197 13810 12280
+8490 9588 8313
+10182 11685 11178
+4952 8082 14037
+2900 12222 11006
+10110 7297 9196
+14038 6277 5578
+7108 10381 14039
+14040 11985 8097
+12765 10534 7229
+2659 12635 14041
+14042 11400 12696
+12404 14043 11359
+576 13605 12518
+12256 13759 9347
+12929 12923 3020
+13921 9814 11571
+13862 14044 12991
+1781 3149 7561
+135 3729 9941
+12219 11961 1281
+12828 13932 4504
+13465 8962 7783
+13615 1505 13561
+11599 1687 12900
+11636 8900 14045
+14046 5432 3662
+9303 9251 10676
+13860 4991 1208
+13085 2926 12838
+1037 10780 8233
+14047 7798 13637
+11841 7760 3026
+8942 9958 13457
+8894 12540 1624
+13743 1545 466
+13436 5579 13588
+4498 1190 6582
+14048 14049 2554
+10781 12142 8166
+2387 12615 14050
+8304 7470 14051
+6349 4428 11803
+7733 13767 11650
+7643 12698 11534
+2492 9534 14052
+13969 12088 11428
+11496 10466 8311
+9813 4759 5820
+1621 9333 10988
+13716 14053 13215
+13257 10771 7064
+4534 8487 10981
+14054 4474 12054
+14055 314 9431
+6097 8609 13479
+10943 11854 11718
+4317 6408 2120
+4760 14056 7908
+12008 7867 8681
+6092 8363 4436
+12521 10227 14057
+1666 11168 9828
+9618 13311 7225
+13985 11724 11765
+6998 9218 13473
+5039 13150 14058
+8201 11348 10694
+11220 8540 12830
+13102 3306 10101
+14059 11130 12301
+13660 13602 13310
+13514 9162 11710
+4878 14060 14061
+5370 14062 14063
+13151 5596 9013
+8998 14064 5930
+1841 6413 8140
+13487 13639 14065
+12815 12260 13321
+6811 6203 14066
+5617 8726 13556
+14067 13717 14068
+13973 14069 13811
+4105 11422 11849
+7169 14070 10815
+6312 11054 10637
+4928 6800 4267
+14071 13042 13875
+3544 2866 4292
+13698 1431 3501
+1160 13964 7386
+5115 13801 11998
+11577 8736 6359
+10190 983 13421
+13938 13686 4899
+12697 14072 13518
+4335 9738 13260
+4834 14073 4949
+12789 11523 14074
+13945 14075 6988
+7263 5595 13703
+14076 13092 13144
+4320 1846 7245
+2970 14077 6546
+14078 14079 13217
+11683 6785 889
+4778 2311 14080
+5634 14081 8399
+13599 11898 14082
+14083 9200 13530
+3956 12371 12037
+13773 12236 1836
+13813 14023 2944
+9064 13045 1435
+7656 12515 11264
+6194 13322 13628
+4868 12339 358
+12529 12375 2167
+9042 14084 3924
+11183 10167 8750
+4043 12653 12193
+14085 12885 9242
+13567 1310 14086
+12453 14087 14088
+14089 9797 9501
+12391 13131 14090
+14091 11124 14052
+14092 13742 11041
+14093 6593 11117
+4044 826 14000
+1987 9808 13237
+10940 7649 1941
+13614 14094 14095
+11807 9832 13108
+5348 13955 8641
+13727 11436 9102
+8470 10207 8292
+10045 9290 11412
+8428 5952 13409
+13117 9262 825
+1114 4035 788
+9394 11989 14096
+11744 13545 14097
+11442 7451 13493
+10265 853 6130
+8075 10854 11952
+4038 6939 5704
+12436 14098 4001
+6461 4074 6036
+12538 13803 12462
+12347 13939 3605
+12429 10374 14099
+9145 13897 14100
+3518 11188 12223
+11993 11353 13685
+11835 13550 638
+13233 8729 7914
+11480 6110 13927
+5923 7383 14032
+7976 14051 491
+8964 10250 10749
+12249 5482 6924
+1820 10194 13135
+13044 10546 13002
+14101 11109 8618
+11856 6451 4645
+5273 13268 2085
+4495 11389 13141
+5110 13959 14102
+7585 11635 14103
+9247 10578 14104
+7563 13749 14105
+6239 10111 979
+14106 14107 14108
+13208 6116 13890
+3591 13350 6614
+8148 7188 11689
+7662 9006 7067
+10605 14109 13523
+12268 14110 6166
+12498 4123 8234
+6525 6710 12300
+2363 1010 12097
+12427 10745 11189
+13053 2392 12825
+2971 12304 10026
+14111 14112 7553
+11217 12756 12063
+12201 2285 14113
+10793 10221 8643
+11872 12826 1715
+12758 6674 7093
+14114 9869 7345
+8194 1969 12777
+13642 14115 4533
+13532 4595 13156
+557 14116 12600
+13842 8147 7025
+3498 12382 5499
+12010 14117 10490
+2395 14118 3239
+9600 13463 9516
+10840 12092 11777
+7453 11980 11097
+13659 10015 11121
+1608 7673 13829
+1612 14119 354
+4129 14120 4013
+8677 7290 11583
+3034 14121 5449
+2454 12069 4984
+11240 12004 4454
+14048 13476 4236
+14122 6683 9390
+9014 10528 10635
+12602 9757 13886
+9325 2963 10373
+1593 11973 408
+13572 1765 13540
+2390 12490 14123
+14124 12130 253
+14108 6171 11408
+6470 14125 2300
+2188 12722 10722
+11637 14083 11892
+13434 4621 11186
+14126 6999 14127
+6177 13520 5546
+290 12487 7698
+9060 13854 14128
+14129 1644 9761
+14130 4695 2891
+13527 5675 5438
+4712 14064 4550
+13223 14107 9920
+10927 11370 5253
+7170 10434 10428
+9403 13867 11170
+6492 10315 10437
+14131 6721 8273
+13364 3031 6624
+4332 443 14132
+14033 13058 4644
+14133 14134 6174
+13865 14135 12226
+12611 6354 9255
+14136 10642 4715
+11828 13999 7051
+1996 12724 14137
+1063 10914 435
+14138 10878 12353
+5809 5024 13834
+13459 6574 14139
+13349 12510 12884
+13942 4531 9327
+8008 7572 10399
+4312 1721 6520
+4656 3385 7661
+14026 6001 11171
+12170 2674 5364
+13924 2371 2187
+12417 9970 14035
+9126 5289 14106
+12152 14140 13598
+8727 14049 3209
+13105 4975 9747
+14141 3002 9049
+9890 3996 10768
+9527 1896 2265
+14142 11787 906
+13818 14143 7775
+617 9784 5942
+13872 14144 1048
+13346 7131 2889
+11972 9054 14145
+3394 14080 10926
+13970 13128 14146
+14147 14148 9750
+5652 13963 9859
+13995 6079 11037
+13060 1020 12454
+12883 13557 3611
+11202 6621 9953
+13468 9898 10199
+12676 8007 12188
+14149 1028 1005
+9933 11157 2190
+14140 13313 14062
+378 3112 11448
+6599 4697 14150
+13294 10283 4514
+7933 6317 14151
+14152 10345 1808
+11398 14153 10279
+4463 5179 5022
+14154 4587 14155
+14156 7376 14157
+3314 11721 5054
+8420 8692 7703
+2164 7570 4254
+8429 797 14158
+10429 1901 12086
+14159 4815 11563
+5325 8877 13174
+9365 13314 10048
+12327 14160 14161
+7864 13089 9955
+2929 13552 14147
+8231 5812 12725
+12807 13484 10671
+6979 14162 13893
+11410 4345 12850
+4598 9641 9298
+10697 14163 8824
+3747 11737 13386
+7771 5436 636
+14164 8279 8992
+13730 6145 12941
+9341 13777 2953
+12389 347 8803
+14165 13410 11693
+11048 12265 13857
+13495 11129 13551
+13226 14117 9387
+14058 14166 13762
+14167 13856 11994
+9158 8789 4561
+1913 9020 13728
+14168 9722 14129
+7260 7499 2088
+12785 13542 13968
+14169 11460 8622
+14170 11179 13706
+5122 12584 14171
+13565 8494 14022
+8369 11911 11274
+11862 8926 1826
+1343 13435 13714
+14172 11716 4189
+7112 5204 14173
+1062 9378 4797
+14174 4185 1068
+14133 9526 8653
+13671 3493 9135
+8717 11060 14061
+13633 10368 8000
+93 14148 2435
+12019 9043 10820
+5825 13983 6954
+14175 7868 14176
+12636 7173 2386
+7918 11317 4279
+12199 13066 14177
+14092 5030 13853
+13782 9803 8299
+14178 671 13262
+459 7328 9957
+14179 10055 9182
+14171 8804 9728
+14180 716 275
+14068 7791 9121
+7552 10417 12481
+4992 3155 4594
+14179 12621 5109
+11618 13593 8527
+9468 14181 1414
+6041 9903 7495
+1911 12123 14096
+9719 14182 1438
+196 11331 5966
+13889 12779 5097
+8662 14183 1662
+11487 2544 2616
+13733 5593 9063
+13492 13312 13077
+14184 9839 6360
+8606 3367 6455
+1185 8742 10614
+13445 7304 8735
+5993 5360 5730
+11083 3619 13458
+8627 1788 4057
+3382 5567 1611
+9871 2859 8247
+10238 14109 10587
+8401 9716 11162
+13965 8558 11981
+137 7296 12771
+4467 13687 12773
+12792 14185 6712
+13704 7854 7104
+13791 709 13997
+13061 6496 13904
+14186 12532 6658
+12211 1168 13474
+12090 3885 1056
+11919 14187 11182
+6669 14134 11432
+13270 14188 14189
+9472 12995 14190
+2221 8868 13389
+14191 8039 14091
+14046 4986 12917
+12568 7089 9474
+8572 1141 14063
+14192 14182 5599
+13937 14193 506
+4365 3211 14194
+6849 12114 12913
+2061 5218 14044
+14104 4115 8990
+10033 5020 13755
+5849 12550 13130
+8757 9022 5828
+14152 10382 14195
+10480 14031 11304
+2455 146 3594
+1633 1223 5914
+9630 10664 13930
+14196 5023 5133
+4415 3109 1915
+12592 4939 14142
+10000 4417 9646
+3288 13821 5867
+14158 6237 12549
+14004 12977 14197
+11958 13696 8961
+11717 14198 14199
+12506 14115 11192
+9614 3059 8408
+2400 2665 7434
+6687 14200 11330
+12638 11062 14201
+13213 10864 9939
+10859 13302 12115
+14202 2954 10147
+13863 4112 14180
+11137 6569 13056
+8497 1473 10184
+11682 4133 5840
+1136 7508 8963
+13279 5939 12197
+807 7620 14154
+14146 3584 14203
+14204 3392 12316
+9491 8375 11071
+10261 13259 8592
+11638 7822 13978
+11248 7956 9098
+14205 11072 7484
+9401 11870 11321
+14206 12920 3638
+11949 10436 13906
+6192 12472 7464
+8413 10512 12753
+3937 1839 13962
+9241 13171 2013
+9086 13913 14122
+5420 10783 13775
+14018 9658 1213
+7945 10286 1823
+7870 6087 4414
+2496 7298 13366
+14207 663 13808
+10979 14185 9160
+13824 9418 8314
+4874 14208 10158
+14003 13885 14013
+2572 11131 5541
+481 7044 13779
+14209 5332 7939
+7390 11452 2533
+1537 2105 2904
+11250 11705 11914
+11431 13796 11475
+11378 13993 8886
+7849 12089 5256
+13589 12504 14172
+14210 5740 6185
+12890 14087 14207
+11104 10365 10094
+1734 11379 3009
+2993 1976 14211
+3793 10865 3355
+11156 7460 11417
+11218 14212 14213
+3935 4297 5203
+9558 12154 14214
+4288 7653 12274
+14215 11338 13761
+9415 13533 12597
+7647 8056 14216
+4788 9692 13515
+11106 4927 10905
+11180 12781 13873
+8111 13926 13701
+3163 14217 5094
+8707 13601 3446
+14218 12543 14206
+12719 10899 1923
+11573 7697 4918
+10115 12364 70
+11150 360 14219
+5148 3387 13902
+9024 13154 13287
+8991 8581 850
+5126 6542 12308
+3235 12648 3465
+3574 14220 9039
+14101 14006 14221
+533 13668 9113
+11373 11932 12867
+10231 11008 13343
+7861 12736 13016
+4039 1684 13289
+7644 13895 13839
+12967 10584 13956
+8392 13847 9937
+13526 1935 6693
+8489 13957 11933
+4130 14222 7587
+3625 170 4713
+11280 5497 12433
+14137 14223 9107
+13018 11066 2837
+9945 10336 2475
+13879 11498 11730
+13715 13815 8391
+13737 4849 7293
+3169 11850 13851
+10449 1884 8073
+10476 12914 12902
+4357 12996 9927
+12979 14224 14225
+13826 14226 14227
+11628 14228 8775
+14229 14181 12601
+9003 13726 10289
+962 7420 13478
+6330 6848 12459
+10275 247 13805
+14105 8658 9319
+13424 7422 14230
+12194 9776 7730
+12907 11116 13238
+2723 8367 14111
+9216 14231 2081
+5802 1496 11176
+1206 14232 14233
+8161 14234 5197
+14235 14236 14237
+9044 11617 11466
+11801 7613 13309
+3479 9709 14238
+941 12173 14162
+4892 14239 5018
+13888 10897 1064
+4965 12425 9334
+13840 10337 13052
+3917 9861 14088
+2785 14240 12710
+13662 12656 8687
+8636 3037 9271
+8235 4181 14169
+3251 13880 12604
+14241 10760 5576
+4491 13046 11260
+10646 13271 8256
+12651 13678 11315
+14242 13626 9715
+836 2232 12393
+3971 7123 8203
+9449 8798 932
+13216 12881 7792
+6947 14243 4373
+9352 876 8198
+7927 12823 14213
+14204 14198 12503
+14055 13752 14034
+6515 14187 2776
+8414 13876 10807
+9605 7594 11986
+12147 6562 6478
+13240 568 8127
+6736 11203 1486
+12818 13388 13954
+12674 12082 14178
+8532 13333 12637
+14244 12922 13798
+11917 9447 1332
+14116 14231 12631
+6371 4572 13359
+4768 5678 6975
+12695 3484 7536
+13998 13323 13644
+6902 6529 3890
+13422 13892 11323
+12329 14126 13073
+2261 10333 14189
+2988 12856 13387
+8699 14163 13846
+12110 3051 5989
+10389 13974 10871
+12318 11540 14245
+14246 12403 14168
+14247 9246 11673
+14099 5487 13984
+2290 13129 11406
+5501 12612 3627
+7164 12693 4015
+14248 12623 12214
+5529 11076 13772
+13200 8012 12250
+14114 2448 14244
+10260 4571 10827
+4569 14249 14250
+13112 7540 14251
+13900 12680 7578
+5274 13283 11281
+9035 8739 4693
+10751 9643 4686
+5883 13699 10855
+9936 14056 13078
+14252 14253 13198
+13261 11303 4336
+10304 12898 10487
+9518 3276 10325
+7121 7617 9780
+10019 10990 12658
+7140 8439 11438
+13920 14222 2126
+7238 4326 11356
+11535 12843 6497
+8347 14045 9556
+14254 7770 14199
+5536 14240 13665
+5149 12718 10844
+1862 9392 11152
+13291 12499 12072
+5481 13661 2673
+10189 14069 14255
+12921 5127 12310
+7399 11662 7940
+11582 12124 7149
+8088 2156 14256
+14257 14258 3776
+10752 6169 6985
+9691 13304 11558
+2213 4800 13896
+13544 13979 8665
+14259 12864 9795
+11982 7651 13996
+8674 8316 7626
+14260 6946 10099
+7231 11975 10497
+1058 9621 7086
+3455 14086 10702
+12546 14261 13499
+14256 14121 14262
+12118 9467 10837
+11332 5372 10415
+13119 2670 913
+10956 2635 11440
+14074 1790 11362
+2661 6038 116
+12406 13265 11351
+7172 122 14125
+13418 6043 14200
+11135 3538 13878
+10868 13850 2339
+6534 12320 12269
+11629 2872 12091
+2458 12891 5684
+9582 3440 12401
+13231 14263 14143
+7669 12524 13916
+2592 1307 12799
+14075 12373 5539
+6045 13822 10707
+700 10202 8808
+12767 12901 5478
+8711 1758 14264
+10856 5335 14265
+12744 14119 8996
+2615 13123 11814
+8112 495 7374
+11488 10934 2230
+12168 3743 9768
+1142 13989 14259
+8831 5524 3495
+8896 14017 13947
+11866 13917 9829
+54 9353 14262
+12295 6625 10696
+13689 14144 14266
+7241 10583 7043
+7215 6957 12203
+12583 11336 11416
+7352 13577 13196
+10993 11391 14267
+7711 10625 10112
+1875 9432 3606
+14268 8156 10558
+13882 11232 14184
+7708 8522 12742
+13579 14249 14040
+2108 1786 3966
+14025 10701 13740
+9717 12556 12493
+5488 6827 12522
+967 11806 5713
+10209 656 14269
+11864 9134 13908
+14270 1422 12052
+10787 11288 14238
+13907 3072 11604
+7266 14271 5073
+11608 10881 1260
+12834 11770 12933
+3477 7781 451
+14097 6017 6280
+8479 8443 13065
+13971 13227 11485
+10555 14272 8055
+3766 5184 8454
+13627 9739 14252
+7175 12849 2384
+13125 11040 11868
+8105 14273 9507
+12439 1111 14065
+13797 13316 9868
+14274 10901 13953
+9374 14239 11028
+12569 6118 8852
+14100 6925 2672
+5138 10414 11486
+12291 12489 9767
+8153 10472 13697
+14113 8577 14153
+12944 11566 14275
+14007 13315 10743
+11276 3489 14112
+13812 6323 14276
+14277 10966 13236
+12253 6005 14012
+11376 11125 2141
+14278 8081 13667
+13014 3213 7412
+9348 62 3681
+12833 14279 14149
+282 13992 7538
+4370 3726 9972
+3549 14157 3663
+3323 10266 12292
+1810 1376 14059
+2607 9887 13758
+4420 9412 8218
+14095 4937 2298
+7670 13746 5411
+7706 3428 8474
+9340 12536 4381
+9650 13398 13629
+11259 14183 13709
+3910 13110 9284
+14118 14193 14160
+13652 5450 2155
+14280 4735 14281
+14282 11632 1674
+1667 5395 12345
+12277 9539 14251
+10277 1603 14221
+14269 11492 8604
+13648 11676 13785
+10388 6765 13771
+10027 7084 13620
+7312 4940 12577
+12455 14283 1847
+11912 11483 3804
+2788 3135 9799
+1089 6460 7221
+2330 11111 3632
+14284 14261 13358
+7047 14173 4296
+2571 4705 13195
+132 11877 3883
+9642 10155 12229
+7511 7057 6726
+1014 9932 14285
+12107 817 12475
+8011 14190 2035
+10972 8702 13382
+13290 12248 14286
+7477 8202 12714
+13734 7196 14233
+68 9217 9703
+9211 10632 12912
+13460 7898 4761
+10051 861 14287
+2779 9589 12942
+8801 14288 14138
+8440 6115 10338
+13505 9846 6240
+14029 1294 13160
+11366 1322 9657
+324 7413 14165
+5209 12322 12707
+2107 9214 14289
+8090 2176 4168
+12845 7408 3108
+14020 14277 5098
+11930 14094 9492
+12706 13861 13604
+6708 5469 13337
+10244 10387 1852
+7138 14290 9259
+14285 5670 2464
+13820 8448 10403
+1031 8512 14242
+13936 4407 13607
+144 12733 11761
+11783 14271 12730
+13949 12067 13408
+6070 1926 6206
+13832 13899 14291
+4070 4720 8189
+12465 10057 3461
+13712 14220 8864
+12694 4286 13442
+13982 2275 13558
+3623 14098 13647
+13975 12965 3536
+11956 10036 4246
+10225 10698 7905
+2036 13651 1683
+5864 11511 6187
+3567 11847 13507
+12844 13948 13595
+2488 10904 6516
+13581 221 4527
+12448 11692 13165
+14011 7274 13483
+5005 12641 13188
+11915 7243 14292
+14293 10288 12278
+13950 12997 12709
+1304 6163 12228
+11110 13681 6891
+12649 2768 6766
+13814 12778 5317
+12434 13019 6138
+13157 14294 5451
+8771 13502 14295
+11418 13137 11464
+7702 12801 14090
+690 11546 9733
+13500 4920 7109
+10366 11767 12862
+14145 14070 14014
+11548 13972 9012
+2537 6740 8559
+13966 2666 11659
+9753 13482 1778
+14027 13663 1404
+13559 6583 1189
+14296 10307 13308
+9942 13008 13450
+2419 2356 11242
+14215 13250 14089
+8149 13320 14019
+13676 11287 13360
+14297 13933 12164
+13334 10016 6338
+14298 2834 692
+13753 7873 11479
+8972 13416 2937
+13158 3151 13720
+14299 10137 14205
+12910 12184 11789
+7040 12246 9122
+3092 9897 14038
+11364 7759 8220
+12418 11595 7427
+14300 12857 14054
+13080 11230 3243
+5212 11913 13031
+12464 4654 6228
+12634 2947 13596
+12919 3021 12572
+6830 10540 3199
+1796 10911 13252
+13763 7009 6006
+14273 2657 14301
+12873 1246 6124
+6141 3957 3244
+6000 13748 1730
+14292 5548 12588
+12865 14234 14302
+14303 7938 5643
+12302 6548 9469
+12317 9295 12471
+13086 6636 10498
+11602 13378 8563
+12964 713 3064
+13329 5495 5320
+13653 13088 4733
+13736 13292 7961
+11225 10709 14279
+10416 13494 7466
+13560 11322 10921
+3291 14304 13529
+14223 10059 7189
+10834 14203 4391
+14255 13870 12270
+10488 12285 5427
+13905 12479 7116
+3225 7471 4973
+14305 8525 12732
+14041 5337 13636
+14161 11421 12468
+859 9770 3948
+14275 7767 5297
+14071 502 3285
+6984 13242 9499
+10792 12497 3541
+13419 6686 5130
+13050 13172 13883
+4073 13204 3317
+4505 12377 12950
+5189 14016 8887
+3641 12100 8716
+12174 13640 8122
+7541 13929 12985
+9794 8698 5082
+11725 6864 3976
+4602 6825 14192
+14301 12863 12507
+13594 14015 14230
+10778 6210 11609
+6894 5033 13819
+13838 2514 14131
+9852 12050 7574
+11181 14306 5963
+9497 11454 10604
+7965 14307 12721
+2202 7954 14308
+3887 12337 13462
+4076 5304 12334
+13206 2549 14309
+5322 11215 14024
+6345 12035 14082
+6881 10775 6009
+13591 12537 376
+5298 11002 10156
+8612 13428 10925
+14264 14008 13928
+2150 12613 11779
+12988 10192 14175
+7755 14309 8416
+9633 10071 10949
+5846 13780 12252
+4477 13781 12182
+11075 5985 11268
+3847 13941 14167
+4210 13361 10788
+349 13444 12183
+1972 2337 11614
+13404 4963 1475
+8193 12820 8308
+6307 13173 12819
+14270 11419 3783
+12234 12116 14299
+11386 9111 14155
+12413 12333 5035
+11411 296 550
+13816 10848 9648
+10883 3677 5202
+14073 14225 3357
+2191 7743 14293
+14310 14311 1824
+2203 13756 5805
+6468 5384 12729
+10226 5367 8109
+2565 10104 11603
+8168 12607 13546
+6393 5779 14156
+1110 13710 14036
+13097 2179 13789
+14312 12361 330
+13181 9017 1680
+5418 11796 12962
+7816 5547 9883
+14313 9306 14314
+14128 13535 3494
+11929 14315 14316
+10049 12974 14315
+14066 1197 11927
+13582 12571 2752
+403 14317 12755
+5642 13977 9272
+6715 7598 8685
+14296 6855 13946
+12217 8876 8466
+13007 571 4416
+3655 10061 6839
+4552 10649 13991
+14298 14136 14247
+11074 645 4306
+4240 14224 14267
+13497 9575 1445
+14318 6081 564
+678 8761 10319
+13724 5502 2149
+3090 13881 12125
+1638 13185 14319
+9300 12411 14320
+4403 14176 10489
+4707 10097 12858
+11619 13385 14320
+10898 9419 11214
+11147 12435 5484
+11314 268 10356
+5581 11664 518
+4097 2368 12225
+13303 10880 5922
+13609 11654 12587
+159 13339 12422
+13211 13836 13799
+12359 6082 11553
+7615 7627 12827
+10127 5515 12117
+6643 8057 12458
+1774 13764 8780
+5295 7566 12331
+9928 13769 10703
+1024 14307 14272
+5822 13363 14067
+7802 14002 6743
+13707 13380 10620
+9748 12668 13324
+14300 1146 14321
+9277 9317 10496
+14322 14274 8293
+3125 8944 11105
+11936 13115 12675
+26 12822 14303
+648 5182 2756
+5766 12412 11627
+13914 12557 1437
+4256 11541 14323
+13617 13960 14248
+9578 3042 7875
+12906 8241 8150
+14324 5232 8714
+8034 3679 11657
+14319 14325 14216
+4427 14243 13541
+5158 10282 14047
+5801 6503 3070
+7218 14325 7761
+9580 2905 9714
+13564 3074 14053
+14042 13517 14246
+13449 12307 4736
+14318 11005 13395
+7380 12020 6375
+3113 10143 13543
+8721 13218 3126
+2090 13033 11888
+12430 4608 12859
+6419 7099 8418
+14305 6316 9806
+14211 5424 14284
+3444 10320 14326
+12314 7734 14139
+2969 13524 12416
+1529 13650 14202
+13075 12181 12632
+10986 10058 14208
+8967 13239 13925
+9355 9864 14266
+12029 359 13307
+11414 10941 12759
+10756 5794 13205
+11349 7163 5683
+12531 5967 8935
+14050 3475 10172
+14232 12047 13142
+8747 4443 1927
+14085 2012 13825
+627 14327 5926
+14308 14217 13757
+2040 10633 10895
+14164 12797 11953
+13778 11667 14236
+7019 11507 3933
+14084 3980 2101
+11474 12112 14328
+13038 12682 9016
+11889 13034 9993
+8224 14130 12846
+12980 11703 14329
+13766 12586 12757
+13431 9573 7668
+4493 13193 6114
+7073 9624 13247
+12121 12437 12580
+730 11051 10842
+6809 14316 3349
+7520 8384 10785
+14010 6885 9057
+14276 12782 14170
+12702 14072 9754
+9629 14228 5913
+4588 12428 12887
+249 1920 9601
+8941 13288 13694
+14201 11671 14005
+14253 13859 11300
+2617 12946 12578
+898 14188 790
+1736 14057 8108
+11687 14310 8424
+8117 14288 13441
+13281 13068 13286
+5583 14290 11172
+11855 13103 14317
+13396 1904 12842
+13553 10420 12040
+14295 10684 7913
+3145 2196 10626
+13354 9830 11830
+11354 13994 14324
+13610 13214 11707
+13352 5437 9765
+14226 8809 10690
+12821 12330 14209
+402 3532 10892
+1854 13420 14330
+8258 10091 7818
+9096 6246 14331
+7194 750 10577
+14329 8594 8227
+10903 7148 14332
+6801 11846 3069
+12829 8441 12993
+5848 667 13012
+7944 6370 939
+14265 13525 2601
+14191 13961 2018
+10078 8338 123
+7835 5361 2663
+13392 6602 14297
+12892 1488 2254
+14093 5645 3900
+4786 12886 14227
+4698 8533 5838
+2921 6729 13677
+8253 4226 3422
+12654 13909 3492
+14250 5898 12319
+12748 11326 2870
+1228 13931 7884
+12056 133 7156
+12973 4960 14257
+9205 14195 14268
+13664 13786 9482
+14287 14263 8334
+1842 12024 14286
+4359 7681 14302
+2790 6073 5818
+9680 12866 8985
+180 8272 4139
+11774 9297 1220
+11740 10494 5255
+4676 4813 14076
+14177 3973 10025
+8956 489 7052
+10492 5527 14174
+10054 14212 13047
+1257 1418 13182
+3148 13093 13702
+14102 4913 11902
+9316 12869 13412
+9363 14333 3228
+2751 14314 13934
+9486 14283 7493
+9293 14235 3543
+7385 12589 7469
+3576 10727 8865
+2005 8845 3572
+6032 11622 12365
+1536 4308 10352
+7736 4040 2222
+5688 2847 13634
+3029 10330 12176
+10098 13976 9191
+5886 14334 3420
+2103 14311 3647
+3406 1430 976
+1771 10343 3277
+13248 5177 12553
+4944 14151 1769
+11088 13152 7962
+4677 12915 12877
+6685 14335 11653
+11382 12793 12445
+13828 5955 12582
+8121 13830 12205
+2065 6921 14124
+7629 12207 7192
+11702 12200 4100
+3262 8503 4618
+11213 11666 13072
+12240 6433 13280
+8989 10817 10845
+14218 11794 12575
+10005 3563 2927
+4959 11934 14291
+11526 14037 14278
+2394 10692 12483
+14289 5398 9713
+14123 13981 7785
+14260 6571 12800
+13719 11845 12212
+10273 6916 14258
+11709 152 10617
+431 4187 6971
+10331 644 11684
+10451 12093 2915
+9189 13817 10679
+7450 14078 3740
+12312 6573 11425
+10092 14132 3409
+14334 11605 14186
+13943 13335 2411
+3227 4808 1040
+1658 9541 11997
+5877 13098 4512
+10689 12213 4930
+106 14127 13472
+13804 7465 9294
+5472 11979 10821
+13374 2845 7317
+3035 13548 11155
+3230 12836 12189
+2172 8696 14313
+11247 2089 2515
+946 351 4934
+14210 10548 7476
+10393 501 13611
+3649 10251 8177
+3565 13429 12501
+14323 5844 11963
+13547 14294 3044
+9186 12106 12370
+14326 5118 13037
+8507 4090 14159
+12787 8410 7932
+12717 9021 9311
+12770 12945 6816
+11283 14120 14333
+9822 8307 839
+9840 11233 11489
+635 252 2830
+11271 51 6796
+14039 11897 2942
+3513 12311 7480
+13695 13864 14009
+13666 8853 162
+14135 13084 8217
+13293 13723 14060
+13306 2722 9672
+14336 11988 4204
+11751 13622 13554
+3689 13166 13510
+14337 12786 13534
+13094 13744 8045
+14141 14332 14338
+14237 11212 10790
+14110 6336 10795
+14219 12028 10735
+12805 13041 13987
+9569 8179 13705
+14197 11861 10309
+13858 9705 11016
+9069 14166 11070
+9227 8776 11782
+12957 11616 3079
+12984 12775 10720
+6442 14030 8020
+2170 13319 7664
+13827 1258 14331
+14028 4101 3353
+977 71 13590
+8336 3816 10052
+8945 1558 14337
+13475 11557 13076
+13783 12488 14229
+12053 5946 7803
+9634 1523 14312
+4943 194 7994
+13501 6498 11881
+11018 3261 13357
+6775 1242 4793
+5859 9142 13139
+9523 9926 13849
+12824 12352 5186
+4399 7054 4402
+14150 14079 8126
+14196 10293 13835
+5973 1284 14282
+9144 11246 12204
+10863 7077 7393
+13741 1452 8635
+12399 13935 11025
+8800 12355 2711
+14335 13874 12585
+9169 14001 7947
+4322 2460 13272
+6994 13713 10013
+13672 307 14077
+9785 12812 10560
+7014 10561 13898
+8514 4750 11890
+1345 10613 9238
+11352 2720 14043
+8154 3400 6750
+13911 5521 14304
+14245 8419 14254
+10889 10479 113
+8546 5558 14194
+11530 10590 9233
+11594 7161 14081
+13491 12963 712
+5994 7999 14321
+10133 13317 7330
+12360 4175 4422
+12156 13373 3968
+13990 13638 8286
+9763 10228 13375
+3298 751 14328
+6781 6780 10242
+14327 9180 3032
+10406 9070 12527
+13958 2524 12390
+3290 5983 11580
+868 7268 11490
+14338 5261 7033
+11826 1909 14336
+13944 10711 2414
+343 8812 9755
+11128 6053 9073
+8708 12598 10204
+11316 10485 13300
+14214 6119 9475
+14281 11007 14306
+3745 2208 7766
+13729 13923 7256
diff --git a/test/nz/nz.gfs b/test/nz/nz.gfs
new file mode 100644
index 0000000..7057c25
--- /dev/null
+++ b/test/nz/nz.gfs
@@ -0,0 +1,74 @@
+# Title: Gravity waves in a realistic ocean basin
+#
+# Description:
+#
+# A tilted ocean surface is initialised in a realistic basin (the Cook
+# strait area in New Zealand). The surface oscillates
+# sending complex gravity waves reflecting off the coast and
+# bathymetry (Figure \ref{p}). No explicit dissipation is added and Figure
+# \ref{k} illustrates the good conservation of the total energy.
+#
+# This is a good test of the robustness of the method when dealing
+# with adaptively refined complex bathymetry.
+#
+# The robustness is controlled essentially by the way face-centred
+# velocity values are computed from cell-centred values.
+#
+# \begin{figure}[htbp]
+# \caption{\label{p}Surface height at $t = 2$.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{p.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{k}Evolution of the kinetic energy.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{k.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: gerris2D3 nz.gfs
+# Version: 1.0.0
+# Required files: nz.gfs bath.gts
+# Generated files: p.eps k.eps
+#
+# Use the "GfsOcean" model
+1 0 GfsOcean GfsBox GfsGEdge {} {
+    # Set the timestep to sthg small compared to the tidal period
+    Time { dtmax = 1e-2 end = 28.5 }
+    # Refine to six levels
+    Refine 6
+    # We want more accuracy in the projection than the default 1e-3
+    ApproxProjectionParams { tolerance = 1e-6 nitermax = 10 }
+    AdvectionParams { scheme = none }
+    Init {} { P = 1e-2*x }
+    # Bathymetry
+    Solid bath.gts
+    # Refine the coastline to 7 levels
+    RefineSurface 7 bath.gts { twod = 1 }
+    # Non-dimensional gravity
+    PhysicalParams { g = 19.62 }
+
+    OutputPPM { start = 2 } { convert ppm:- p.eps } { v = P min = -5e-3 max = 5e-3 }
+    OutputScalarSum { istep = 10 } k { v = Velocity2 }
+    EventScript { start = end } {
+        gnuplot <<EOF
+            set term postscript eps color lw 3 solid 20
+            set output 'k.eps'
+            set xlabel 'Time'
+            set ylabel 'Kinetic energy'
+            set grid
+            plot 'k' u 3:5 w l t ''
+EOF
+        if awk '{if ($5 > 4e-7) exit (1);}' < k ; then
+            return 0;
+        else
+            return $GFS_STOP;
+        fi
+    }
+}
+GfsBox {
+    front = Boundary
+}
diff --git a/test/oscillation/fit.ref b/test/oscillation/fit.ref
new file mode 100644
index 0000000..fed8bde
--- /dev/null
+++ b/test/oscillation/fit.ref
@@ -0,0 +1,4 @@
+5 0.000262644998808499 2.09156892219132 150.364967186
+6 0.000278820242460604 0.612581630706214 153.065777805706
+7 0.000285328887705565 0.217314392890076 154.499228064224
+8 0.000291359142215191 0.101175013065393 154.793056509618
diff --git a/test/oscillation/oscillation.gfs b/test/oscillation/oscillation.gfs
new file mode 100644
index 0000000..1b59d0b
--- /dev/null
+++ b/test/oscillation/oscillation.gfs
@@ -0,0 +1,117 @@
+# Title: Shape oscillation of an inviscid droplet
+#
+# Description:
+#
+# A two-dimensional elliptical droplet (density ratio 1/1000) is
+# released in a large domain. Under the effect of surface-tension the
+# shape of the droplet oscillates around its (circular) equilibrium
+# shape. The fluids inside and outside the droplet are inviscid so
+# ideally no damping of the oscillations should occur. As illustrated
+# on Figure \ref{kinetic} some damping occurs in the simulation due to
+# numerical dissipation.
+#
+# This simulation is also a stringent test case of the accuracy of the
+# surface tension representation as no explicit viscosity can damp
+# eventual parasitic currents.
+#
+# \begin{figure}[htbp]
+# \caption{\label{kinetic}Evolution of the kinetic energy as a function
+# of time for the spatial resolutions indicated in the legend. The
+# black lines are fitted decreasing exponential functions.}
+# \begin{center}
+# \includegraphics[width=0.9\hsize]{k.eps}
+# \end{center}
+# \end{figure}
+#
+# The initial shape of the droplet is given by:
+# $$r(\theta) = r_0 + \alpha\cos(n\theta)$$
+# The oscillation frequency is then \cite{torres00}:
+# $$\omega_n^2={(n^3-n)\sigma\over (\rho_d+\rho_e)r_0^3}$$
+#
+# A comparison between the theoretical and numerical values of the
+# frequency is given in Figure \ref{frequency}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{frequency}Relative error in the oscillation
+# frequency as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{frequency.eps}
+# \end{center}
+# \end{figure}
+#
+# The amount of numerical damping can be estimated by computing an
+# equivalent viscosity. With viscosity, kinetic energy is expected to
+# decrease as:
+# $$\exp(-C\nu/D^2t)$$
+# where $C$ is a constant, $\nu$ the viscosity and $D$ the droplet
+# diameter. Using curve fitting the damping coefficient $b=C\nu/D^2$
+# can be estimated (black curves on Figure \ref{kinetic}). An
+# equivalent Laplace number can then be computed as:
+# $$La={\sigma D\over \rho\nu^2}={\sigma C^2 \over \rho b^2 D^3}$$
+# The equivalent Laplace number depends on spatial resolution as
+# illustrated in Figure \ref{laplace}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{laplace}Equivalent Laplace number estimated from the
+# numerical damping of kinetic energy.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{laplace.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh oscillation.sh
+# Version: 1.2.0
+# Required files: oscillation.sh fit.ref
+# Running time: 3 minutes
+# Generated files: frequency.eps k.eps laplace.eps
+#
+Define DIAMETER 0.2
+Define EPSILON 0.05
+Define VAR(T,min,max)   (min + CLAMP(T,0,1)*(max - min))
+Define RHO(T)            VAR(T, 1., 1e-3)
+Define RADIUS(x,y)      (DIAMETER/2.*(1. + EPSILON*cos (2.*atan2 (y, x))))
+
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+    Time { end = 1 }
+
+    Refine LEVEL
+ 
+    VariableTracerVOF T
+    VariableFiltered T1 T 1
+    InitFraction T ({ x += 0.5; y += 0.5; return x*x + y*y - RADIUS(x,y)*RADIUS(x,y); })
+
+    PhysicalParams { alpha = 1./RHO(T1) }
+    VariableCurvature K T
+    SourceTension T 1. K
+
+    # fixme: A small amount of viscosity seems to be necessary to
+    # obtain a non-increasing kinetic energy at high-resolution (8
+    # levels).
+    SourceViscosityExplicit 7e-5*RHO(T1)
+
+    AdaptFunction { istep = 1 } {
+        cmax = 0.01
+        maxlevel = LEVEL
+    } (T > 0 && T < 1 ? 1. : fabs (Vorticity)*ftt_cell_size (cell))
+
+    OutputScalarSum { istep = 1 } k-LEVEL {
+        v = RHO(T1)*Velocity2
+    }
+
+    EventScript { start = end } {
+        cat <<EOF | gnuplot 2>&1 | awk '{if ($1 == "result:") print LEVEL,$2,$3,$4;}'
+           k(t)=a*exp(-b*t)*(cos(c*t+3.14159265359)+1.)
+           a = 3e-4
+           b = 1.5
+           c = 153
+           fit k(x) 'k-LEVEL' u 3:5 via a,b,c
+           print "result: ", a, b, c       
+EOF
+        rm -f fit.log
+    }
+}
+GfsBox {
+    left = Boundary
+    bottom = Boundary
+}
diff --git a/test/oscillation/oscillation.sh b/test/oscillation/oscillation.sh
new file mode 100644
index 0000000..b2ab535
--- /dev/null
+++ b/test/oscillation/oscillation.sh
@@ -0,0 +1,72 @@
+levels="5 6 7 8"
+
+if ! $donotrun; then
+    rm -f fit
+    for level in $levels; do
+	if gerris2D -D LEVEL=$level oscillation.gfs >> fit; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+rm -f fit-*
+if awk '{
+  level = $1; a = $2; b = $3; c = $4;
+  for (t = 0; t <= 1.; t += 0.005)
+    print t, 2.*a*exp(-b*t) >> "fit-" level;
+}' < fit ; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+
+    D = 0.2
+    n = 2.
+    sigma = 1.
+    rhol = 1.
+    rhog = 1./1000.
+    r0 = 0.1
+    omega0 = sqrt((n**3-n)*sigma/((rhol+rhog)*r0**3))
+
+    set output 'k.eps'
+    set xlabel 'Time'
+    set ylabel 'Kinetic energy'
+    set logscale y
+    plot [0:1][8e-5:]'k-8' u 3:5 t "256x256" w l, 'k-7' u 3:5 t "128x128" w l, 'k-6' u 3:5 t "64x64" w l, 'k-5' u 3:5 t "32x32" w l, 'fit-8' t "fit" w l lt 7, 'fit-7' t "" w l lt 7, 'fit-6' t "" w l lt 7, 'fit-5' t "" w l lt 7
+
+    set output 'laplace.eps'
+    set xlabel 'Diameter (grid points)'
+    set ylabel 'Equivalent Laplace number'
+    set logscale y
+    set logscale x 2
+    set grid
+    empirical_constant = 30.
+    plot 'fit' u (D*2.**(\$1)):(1./(\$3**2.*D**3.))*empirical_constant**2. t "" w lp pt 5 ps 2
+
+    unset logscale
+    set output 'frequency.eps'
+    set xlabel 'Diameter (grid points)'
+    set ylabel 'Frequency error (%)'
+    unset grid
+    set xzeroaxis
+    plot 'fit' u (D*2.**(\$1)):(\$4/2./omega0-1.)*100. t "" w lp pt 5 ps 2
+
+    
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('fit',1,3) - Curve('fit.ref',1,3)).max() > 1e-2 or\
+   (Curve('fit',1,4) - Curve('fit.ref',1,4)).max() > 1e-2:
+  exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/parabola/error.ref b/test/parabola/error.ref
new file mode 100644
index 0000000..2cdfcb7
--- /dev/null
+++ b/test/parabola/error.ref
@@ -0,0 +1,5 @@
+5 0.00643516 0.0111809 0.07844
+6 0.00208764 0.00386098 0.04185
+7 0.000928116 0.00176718 0.03133
+8 0.000629843 0.00118686 0.03369
+9 0.000616878 0.00111956 0.03758
diff --git a/test/parabola/order.ref b/test/parabola/order.ref
new file mode 100644
index 0000000..eeff67c
--- /dev/null
+++ b/test/parabola/order.ref
@@ -0,0 +1,4 @@
+6 1.6241 1.534 0.906362
+7 1.1695 1.12752 0.417683
+8 0.559313 0.574299 -0.104776
+9 0.0300071 0.0842179 -0.157645
diff --git a/test/parabola/parabola.gfs b/test/parabola/parabola.gfs
new file mode 100644
index 0000000..f5668c7
--- /dev/null
+++ b/test/parabola/parabola.gfs
@@ -0,0 +1,118 @@
+# Title: Oscillations in a parabolic container
+#
+# Description:
+#
+# Analytical solutions for the damped oscillations of a liquid in a
+# parabolic container have been derived by Sampson et al
+# \cite{sampson2006,liang2008}. Figure \ref{elevation} illustrates the
+# numerical and analytical solutions at $t = 1500$ seconds.  Wetting
+# and drying occur at the two moving contact points and hydrostatic
+# balance is approached as time passes.
+#
+# Figure \ref{u0} gives the analytical and numerical solutions for the
+# horizontal component of velocity (which is spatially
+# constant). Figures \ref{error} and \ref{error-u} give the relative
+# errors in surface elevation and horizontal velocity respectively, as
+# functions of spatial resolution. Figures \ref{order} and
+# \ref{order-u} give the corresponding convergence orders.
+#
+# The errors are generally small, however convergence is not reached
+# with increasing resolution. This is due to errors in velocity at the
+# contact points.
+#
+# \begin{figure}[htbp]
+# \caption{\label{elevation}Solution at $t = 1500$ seconds. Six levels of refinement.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{elevation.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{u0}Time evolution of the (spatially constant)
+# horizontal velocity. Seven levels of refinement.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{u0.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the relative elevation error norms as functions of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error-u}Evolution of the relative velocity error
+# L2-norm as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error-u.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order-u}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order-u.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh parabola.sh
+# Version: 1.3.1
+# Required files: parabola.sh error.ref order.ref
+# Generated files: elevation.eps error.eps error-u.eps order.eps order-u.eps u0.eps
+#
+Define h0 10.
+Define a 3000.
+Define tau 1e-3
+Define B 5
+Define G 9.81
+
+1 0 GfsRiver GfsBox GfsGEdge {} {
+
+    # Analytical solution, see Sampson, Easton, Singh, 2006
+    Global {
+	static gdouble Psi (double x, double t) {
+	    double p = sqrt (8.*G*h0)/a;
+	    double s = sqrt (p*p - tau*tau)/2.;
+	    return a*a*B*B*exp (-tau*t)/(8.*G*G*h0)*(- s*tau*sin (2.*s*t) + 
+		(tau*tau/4. - s*s)*cos (2.*s*t)) - B*B*exp(-tau*t)/(4.*G) -
+	    exp (-tau*t/2.)/G*(B*s*cos (s*t) + tau*B/2.*sin (s*t))*x;
+	}
+    }
+
+    PhysicalParams { L = 10000 }
+    RefineSolid LEVEL
+    Solid (y/10000. + 1./pow(2,LEVEL) - 1e-6 - 0.5)
+    Init {} {
+	Zb = h0*(x/a)*(x/a)
+	P = MAX (0., h0 + Psi (x, 0.) - Zb)
+    }
+    Init { istep = 1 } {
+	Pt = MAX (0., h0 + Psi (x, t) - Zb)
+    }
+    PhysicalParams { g = G }
+    SourceCoriolis 0 tau
+    Time { end = 6000 }
+    OutputSimulation { start = 1500 } sim-LEVEL-%g.txt { format = text }
+    OutputSimulation { start = end } end-LEVEL.txt { format = text }
+    OutputScalarSum { istep = 10 } ke-LEVEL { v = (P > 0. ? U*U/P : 0.) }
+    OutputScalarSum { istep = 10 } vol-LEVEL { v = P }
+    OutputScalarSum { istep = 10 } U-LEVEL { v = U }
+    OutputErrorNorm { istep = 1 } error-LEVEL { v = P } {
+	s = Pt
+	v = DP
+    }
+}
+GfsBox {
+    left = Boundary
+    right = Boundary
+}
diff --git a/test/parabola/parabola.sh b/test/parabola/parabola.sh
new file mode 100644
index 0000000..3e340cf
--- /dev/null
+++ b/test/parabola/parabola.sh
@@ -0,0 +1,162 @@
+levels="5 6 7 8 9"
+
+if ! $donotrun; then
+    for level in $levels; do
+	if gerris2D -DLEVEL=$level parabola.gfs; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+for level in $levels; do
+    awk -v level=$level 'BEGIN{
+      s1 = 0.;
+      s2 = 0.;
+      smax = 0.;
+      n = 0;
+      h0 = 10.;
+    }{
+      n++;
+      s1 += $5;
+      s2 += $7*$7;
+      if ($9 > smax) smax = $9;
+    }END { print level, s1/n/h0, sqrt(s2/n)/h0, smax/h0; }' < error-$level
+done > error
+
+for level in $levels; do
+    if  paste U-$level vol-$level | awk -v level=$level 'BEGIN {
+      sum = 0.; 
+      n = 0; 
+
+      h0 = 10.
+      a = 3000.
+      tau = 1e-3
+      B = 5.
+      G = 9.81
+      p = sqrt (8.*G*h0)/a
+      s = sqrt (p*p - tau*tau)/2.
+    } {
+          u0 = $5/$10;
+          t = $3;
+          ref = B*exp (-tau*t/2.)*sin (s*t);
+          sum += (u0 - ref)*(u0 - ref);
+          n += 1;
+        }
+        END {
+          print level, sqrt (sum/n);
+        }'; then
+	:
+    else
+	exit 1;
+    fi
+done > error-u
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n1[n] = $2; n2[n] = $3; ni[n++] = $4;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n1[i-1]/n1[i])/log(2.) " " log(n2[i-1]/n2[i])/log(2.) " " log(ni[i-1]/ni[i])/log(2.);
+}' < error > order; then :
+else
+    exit 1
+fi
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n2[n++] = $2;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n2[i-1]/n2[i])/log(2.);
+}' < error-u > order-u; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+
+    set output 'error.eps'
+    set xlabel 'Level'
+    set ylabel 'Relative error norms'
+    set key
+    set logscale y
+    set xtics 0,1
+    set grid
+    plot 'error.ref' u 1:2 t '1 (ref)' w lp, \
+         'error.ref' u 1:3 t '2 (ref)' w lp, \
+         'error.ref' u 1:4 t 'max (ref)' w lp, \
+         'error' u 1:2 t '1' w lp, \
+         'error' u 1:3 t '2' w lp, \
+         'error' u 1:4 t 'max' w lp
+   
+    set output 'error-u.eps'
+    set ylabel 'u0 relative error L2 norm'
+    plot 'error-u' u 1:(\$2/4.) t '' w lp
+   
+    set output 'order.eps'
+    set xlabel 'Level'
+    set ylabel 'Order'
+    unset logscale
+    set ytics 0,1
+    plot [][-1:2] 'order.ref' u 1:2 t '1 (ref)' w lp, \
+                  'order.ref' u 1:3 t '2 (ref)' w lp, \
+                  'order.ref' u 1:4 t 'max (ref)' w lp, \
+                  'order' u 1:2 t '1' w lp, \
+                  'order' u 1:3 t '2' w lp, \
+                  'order' u 1:4 t 'max' w lp
+
+    set output 'order-u.eps'
+    plot [][-1:2]'order-u' u 1:2 t '' w lp
+
+    set output 'u0.eps'
+
+    h0 = 10.
+    a = 3000.
+    tau = 1e-3
+    B = 5.
+    G = 9.81
+    p = sqrt (8.*G*h0)/a
+    s = sqrt (p*p - tau*tau)/2.
+    u0(t) = B*exp (-tau*t/2.)*sin (s*t)
+
+    set xtics auto
+    set ytics auto
+    unset grid
+    set ylabel 'u0'
+    set xlabel 'Time'
+    plot u0(x) t 'Analytical', '< paste U-7 vol-7' u 3:(\$5/\$10) every 2 w p t 'Gerris'
+
+    set output 'elevation.eps'
+    set xlabel 'x (m)'
+    set ylabel 'z (m)'
+    t = 1500
+    psi(x) = a*a*B*B*exp (-tau*t)/(8.*G*G*h0)*(- s*tau*sin (2.*s*t) + \
+      (tau*tau/4. - s*s)*cos (2.*s*t)) - B*B*exp(-tau*t)/(4.*G) - \
+      exp (-tau*t/2.)/G*(B*s*cos (s*t) + tau*B/2.*sin (s*t))*x + h0
+    bed(x) = h0*(x/a)**2
+    set key top center
+    plot [-5000:5000] \
+      'sim-6-1500.txt' u 1:7:8 w filledcu lc 3 t 'Numerical', \
+      psi(x) > bed(x) ? psi(x) : bed(x) lc 2 t 'Analytical', \
+      bed(x) lw 3 lc 1 lt 1 t 'Bed profile'
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('error',1,4) - Curve('error.ref',1,4)).max() > 1e-3:
+    print (Curve('error',1,4) - Curve('error.ref',1,4)).max()
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/periodic/periodic.gfs b/test/periodic/periodic.gfs
new file mode 100644
index 0000000..30a9245
--- /dev/null
+++ b/test/periodic/periodic.gfs
@@ -0,0 +1,65 @@
+# Title: Convergence for a simple periodic problem
+#
+# Description:
+#
+# This is one of the test cases presented in Popinet \cite{popinet2003}.
+# Following Minion \cite{minion96} and Almgren et al. \cite{almgren98},
+# this convergence test illustrates the second-order
+# accuracy of Gerris for flows without solid boundaries. This
+# problem uses a square unit domain with periodic boundary conditions in
+# both directions. The initial conditions are taken as
+# \begin{eqnarray*}
+# u(x,y) &=& 1-2\cos(2\pi x)\sin(2\pi y), \\
+# v(x,y) &=& 1+2\sin(2\pi x)\cos(2\pi y). 
+# \end{eqnarray*}
+# The exact solution of the Euler equations for these initial conditions
+# is
+# \begin{eqnarray*}
+# u(x,y,t) &=& 1-2\cos(2\pi(x-t))\sin(2\pi(y-t)), \\
+# v(x,y,t) &=& 1+2\sin(2\pi(x-t))\cos(2\pi(y-t)), \\
+# p(x,y,t) &=& -\cos(4\pi(x-t))-\cos(4\pi(y-t)).
+# \end{eqnarray*}
+# As in \cite{almgren98} nine runs are performed on grids with $L=5,6$
+# and $7$ levels of refinement (labelled ``uniform'') and with one
+# (labelled $r=1$) or two (labelled $r=2$) additional levels added only
+# within the square defined by the points $(-0.25,-0.25)$ and
+# $(0.25,0.25)$. The length of the run for each case is 0.5, the CFL number is
+# 0.75. For each run both the $L_2$ and $L_\infty$ norms of the error in
+# the $x$-component of the velocity is computed. Table \ref{minion1}
+# gives the errors and order of convergence obtained.
+#
+# Close to second-order convergence is obtained (asymptotically in
+# $L$) for the $L_2$ and $L_\infty$ norms. The values
+# obtained are comparable to that in \cite{minion96,almgren98}.
+# \begin{table}
+# \caption{\label{minion1}Errors and convergence orders in the $x$-component of the velocity
+# for a simple periodic problem. The reference solution values are given in blue.}
+# \begin{center}
+# \input{minion1.tex}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh periodic.sh periodic.gfs
+# Version: 0.6.4
+# Required files: periodic.sh r0.ref r1.ref r2.ref
+# Running time: 3 minutes
+# Generated files: minion1.tex
+#
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 0.5 }
+  AdvectionParams { cfl = 0.75 }
+  Refine (x < -0.25 || x > 0.25 || y < -0.25 || y > 0.25 ? LEVEL : LEVEL + BOX)
+  Init {} {
+    U = (1. - 2.*cos (2.*M_PI*x)*sin (2.*M_PI*y))
+    V = (1. + 2.*sin (2.*M_PI*x)*cos (2.*M_PI*y))
+  }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  OutputErrorNorm { start = end } stdout { v = U } {
+    s = (1. - 2.*cos (2.*M_PI*(x - t))*sin (2.*M_PI*(y - t)))
+  }
+}
+GfsBox {}
+1 1 right
+1 1 top
diff --git a/test/periodic/periodic.sh b/test/periodic/periodic.sh
new file mode 100644
index 0000000..64b91f5
--- /dev/null
+++ b/test/periodic/periodic.sh
@@ -0,0 +1,74 @@
+if ! $donotrun; then
+    rm -f r0 r1 r2
+
+    for r in 0 1 2; do
+	for level in 5 6 7; do
+	    if sed "s/LEVEL/$level/g" < $1 | \
+		sed "s/BOX/$r/g" | \
+		gerris2D - | \
+		awk -v level=$level '{
+                  print level " " $7 " " $9
+                }' >> r$r; then :
+	    else
+		exit 1
+	    fi
+	done
+    done
+fi
+
+if cat <<EOF | python > minion1.tex; then :
+from check import *
+from sys import *
+from math import *
+
+print r"""\begin{tabular}{|c|c|c|c|c|c|}\hline
+        & \multicolumn{5}{c|}{\$L_2\$} \\\ \hline
+        & \$L=5\$   & \$O_2\$ & \$L=6\$    & \$O_2\$ & \$L=7\$  \\\ \hline"""
+
+def order(r,color='black'):
+   for i in range(0,len(r.l)-1):
+     y0,y1 = r.l[i][1],r.l[i+1][1]
+     print '& {\color{%s}%.2e} & {\color{%s}%4.2f}' % (color, y0, color, log(y0/y1)/log(2.)),
+   print '& {\color{%s}%.2e}' % (color, r.l[i+1][1]), r'\\\'
+
+print 'Uniform',
+order(Curve('r0',1,2))
+order(Curve('r0.ref',1,2),'blue')
+print '\$r=1\$',
+order(Curve('r1',1,2))
+order(Curve('r1.ref',1,2),'blue')
+print '\$r=2\$',
+order(Curve('r2',1,2))
+order(Curve('r2.ref',1,2),'blue')
+
+print r"""\hline
+        & \multicolumn{5}{c|}{\$L_\infty\$} \\\ \hline
+        & \$L=5\$   & \$O_\infty\$  & \$L=6\$   & \$O_\infty\$  & \$L=7\$ \\\ \hline"""
+
+print 'Uniform',
+order(Curve('r0',1,3))
+order(Curve('r0.ref',1,3),'blue')
+print '\$r=1\$',
+order(Curve('r1',1,3))
+order(Curve('r1.ref',1,3),'blue')
+print '\$r=2\$',
+order(Curve('r2',1,3))
+order(Curve('r2.ref',1,3),'blue')
+
+print r"\hline\end{tabular}"
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+for r in ['r0','r1','r2']:
+  if (Curve(r,1,2) - Curve(r+'.ref',1,2)).max() > 1e-6 or\
+     (Curve(r,1,3) - Curve(r+'.ref',1,3)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/periodic/r0.ref b/test/periodic/r0.ref
new file mode 100644
index 0000000..d9575bb
--- /dev/null
+++ b/test/periodic/r0.ref
@@ -0,0 +1,3 @@
+5 8.268e-03 1.966e-02
+6 1.155e-03 3.104e-03
+7 2.073e-04 5.080e-04
diff --git a/test/periodic/r1.ref b/test/periodic/r1.ref
new file mode 100644
index 0000000..1a1ba87
--- /dev/null
+++ b/test/periodic/r1.ref
@@ -0,0 +1,3 @@
+5 8.351e-03 2.200e-02
+6 1.705e-03 4.765e-03
+7 3.960e-04 1.144e-03
diff --git a/test/periodic/r2.ref b/test/periodic/r2.ref
new file mode 100644
index 0000000..5fdf5ba
--- /dev/null
+++ b/test/periodic/r2.ref
@@ -0,0 +1,3 @@
+5 1.062e-02 2.821e-02
+6 2.505e-03 6.545e-03
+7 6.242e-04 1.652e-03
diff --git a/test/plate/plate.gfs b/test/plate/plate.gfs
new file mode 100644
index 0000000..0f4ad83
--- /dev/null
+++ b/test/plate/plate.gfs
@@ -0,0 +1,27 @@
+# Title: Potential flow around a thin plate
+#
+# Description:
+#
+# This test case triggers an instability if the cell-centered pressure
+# gradient used in the approximate projection is not computed using
+# solid-fraction-weighted averages of the face-centered pressure
+# gradients.
+#
+# Author: St\'ephane Popinet
+# Command: sh plate.sh plate.gfs
+# Version: 1.1.2
+# Required files: plate.sh
+#
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+  Time { iend = 30 dtmax = 1e-2 }
+  Refine 5
+  RefineSolid 6
+  Solid (cube(0,0,0,0.5)) { sy = 0.06251 tx = 0.031249 ty = -0.015 }
+  AdvectionParams { scheme = none }
+  Init {} { U = 1 }
+  OutputScalarNorm { start = end } stdout { v = Velocity } 
+}
+GfsBox {
+  left = Boundary { BcDirichlet U 1 }
+  right = BoundaryOutflow 
+}
diff --git a/test/plate/plate.sh b/test/plate/plate.sh
new file mode 100644
index 0000000..954f0df
--- /dev/null
+++ b/test/plate/plate.sh
@@ -0,0 +1,5 @@
+if gerris2D $1 | awk '{ if ($9 < 10.) exit (1); }'; then :
+    exit 1
+else
+    exit 0
+fi
diff --git a/test/poiseuille/error.ref b/test/poiseuille/error.ref
new file mode 100644
index 0000000..94b0a33
--- /dev/null
+++ b/test/poiseuille/error.ref
@@ -0,0 +1,4 @@
+3 1.953e-03 1.953e-03 1.953e-03
+4 4.883e-04 4.883e-04 4.884e-04
+5 1.223e-04 1.223e-04 1.224e-04
+6 3.084e-05 3.084e-05 3.103e-05
diff --git a/test/poiseuille/poiseuille.gfs b/test/poiseuille/poiseuille.gfs
new file mode 100644
index 0000000..6b42cd3
--- /dev/null
+++ b/test/poiseuille/poiseuille.gfs
@@ -0,0 +1,53 @@
+# Title: Poiseuille flow
+#
+# Description:
+#
+# A simple parabolic Poiseuille flow in a periodic channel with a
+# constant along-channel acceleration $a$. The theoretical solution is given by:
+# $$u(y)={a\over 2\nu}(1/4-y^2)$$
+# Figure \ref{convergence} illustrates the maximum error between the
+# computed and theoretical solutions as a function of spatial
+# resolution.
+#
+# \begin{figure}[htbp]
+# \caption{\label{convergence}Convergence of the maximum error as a function
+# of resolution (number of grid points across the channel).}
+# \begin{center}
+# \includegraphics[width=\hsize]{convergence.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh poiseuille.sh
+# Version: 1.2.0
+# Required files: poiseuille.sh error.ref
+# Generated files: convergence.eps
+#
+1 1 GfsSimulation GfsBox GfsGEdge {} {
+    Refine LEVEL
+    # use backward Euler to avoid Crank-Nicholson oscillations in time
+    SourceViscosity 1. { beta = 1 }
+    Source U 1
+
+    # we need this so that acceleration can be balanced by viscous stress
+    # and yes, fixme, this is a mess...
+    AdvectionParams { gc = 1 }
+
+    EventStop { istep = 1 } U 1e-6 DU
+    ProjectionParams { tolerance = 1e-6 }
+    ApproxProjectionParams { tolerance = 1e-6 }
+    OutputErrorNorm { start = end } { awk '{print LEVEL,$5,$7,$9}' } { v = U } { 
+        s = 1./2.*(1./4 - y*y) 
+    }
+}
+GfsBox {
+    bottom = Boundary {
+        BcDirichlet U 0 
+        BcDirichlet V 0 
+    }
+    top = Boundary {
+        BcDirichlet U 0 
+        BcDirichlet V 0 
+    }
+}
+1 1 right
diff --git a/test/poiseuille/poiseuille.sh b/test/poiseuille/poiseuille.sh
new file mode 100644
index 0000000..f9d894a
--- /dev/null
+++ b/test/poiseuille/poiseuille.sh
@@ -0,0 +1,35 @@
+levels="3 4 5 6"
+
+if ! $donotrun; then
+    rm -f error
+    for level in $levels; do
+	if gerris2D -DLEVEL=$level poiseuille.gfs >> error; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'convergence.eps'
+    set xlabel 'Number of grid points'
+    set ylabel 'Maximum error'
+    set logscale
+    set grid
+    set xtics 2
+    plot [6:80]'error' u (2**\$1):4 w lp t 'Gerris' pt 5, 1./x**2./5. t 'second order'
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('error',1,4) - Curve('error.ref',1,4)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/poisson/circle/circle.gfs b/test/poisson/circle/circle.gfs
new file mode 100644
index 0000000..ed98de4
--- /dev/null
+++ b/test/poisson/circle/circle.gfs
@@ -0,0 +1,72 @@
+# Title: Convergence with a refined circle
+#
+# Description:
+#
+# Same as the previous test but in order to test the accuracy of the
+# gradient operator at coarse/fine boundaries, two levels of
+# refinement are added in a circle centered on the origin and of
+# radius 0.25.
+#
+# The solver still shows second-order accuracy in all norms (Figure \ref{order}).
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../poisson.sh circle.gfs
+# Version: 0.8.0
+# Required files: res-7.ref error.ref order.ref
+# Generated files: residual.eps rate.eps error.eps order.eps
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+  Time { iend = 10 }
+  Refine (x*x + y*y <= 0.25*0.25 ? LEVEL + 2 : LEVEL)
+  ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 }
+  Init {} {
+    Div = {
+      int k = 3, l = 3;
+      return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+    }
+  }
+  OutputTime { istep = 1 } {
+      awk '{print n++, $8}' > time
+  }
+  OutputProjectionStats { istep = 1 } {
+    awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+  }
+  OutputErrorNorm { start = end } {
+    awk '{print LEVEL " " $5 " " $7 " " $9}' >> error 
+  } { v = P } {
+    s = (sin (M_PI*3.*x)*sin (M_PI*3.*y))
+    unbiased = 1
+  }
+}
+GfsBox {}
diff --git a/test/poisson/circle/error.ref b/test/poisson/circle/error.ref
new file mode 100644
index 0000000..73fef24
--- /dev/null
+++ b/test/poisson/circle/error.ref
@@ -0,0 +1,6 @@
+3 6.498e-02 9.917e-02 2.281e-01
+4 9.684e-03 1.260e-02 2.883e-02
+5 2.961e-03 3.878e-03 1.279e-02
+6 8.035e-04 1.046e-03 3.391e-03
+7 2.114e-04 2.757e-04 9.282e-04
+8 5.384e-05 7.025e-05 2.373e-04
diff --git a/test/poisson/circle/order.ref b/test/poisson/circle/order.ref
new file mode 100644
index 0000000..480c56f
--- /dev/null
+++ b/test/poisson/circle/order.ref
@@ -0,0 +1,5 @@
+4 2.74632 2.97648 2.98402
+5 1.70952 1.70004 1.17255
+6 1.88171 1.89043 1.91523
+7 1.92632 1.92371 1.8692
+8 1.97323 1.97253 1.96772
diff --git a/test/poisson/circle/res-7.ref b/test/poisson/circle/res-7.ref
new file mode 100644
index 0000000..1f679e2
--- /dev/null
+++ b/test/poisson/circle/res-7.ref
@@ -0,0 +1,11 @@
+0 0.00000000 1.777e+02 0
+1 0.34000000 2.362e+01 7.5
+2 0.64000000 1.191e+00 12
+3 0.93000000 5.505e-02 15
+4 1.23000000 3.880e-03 15
+5 1.53000000 3.184e-04 14
+6 1.82000000 2.607e-05 14
+7 2.11000000 2.106e-06 14
+8 2.41000000 1.694e-07 13
+9 2.71000000 1.368e-08 13
+10 3.01000000 1.110e-09 13
diff --git a/test/poisson/error.ref b/test/poisson/error.ref
new file mode 100644
index 0000000..84d535e
--- /dev/null
+++ b/test/poisson/error.ref
@@ -0,0 +1,6 @@
+3 5.097e-02 6.208e-02 1.194e-01
+4 1.196e-02 1.471e-02 2.914e-02
+5 2.945e-03 3.630e-03 7.243e-03
+6 7.334e-04 9.046e-04 1.808e-03
+7 1.832e-04 2.260e-04 4.518e-04
+8 4.578e-05 5.648e-05 1.130e-04
diff --git a/test/poisson/order.ref b/test/poisson/order.ref
new file mode 100644
index 0000000..c1b1aea
--- /dev/null
+++ b/test/poisson/order.ref
@@ -0,0 +1,5 @@
+4 2.09143 2.07733 2.03473
+5 2.02188 2.01876 2.00834
+6 2.0056 2.00462 2.00219
+7 2.00118 2.00096 2.00064
+8 2.00063 2.00051 1.99936
diff --git a/test/poisson/poisson.gfs b/test/poisson/poisson.gfs
new file mode 100644
index 0000000..9766f98
--- /dev/null
+++ b/test/poisson/poisson.gfs
@@ -0,0 +1,83 @@
+# Title: Convergence of the Poisson solver
+#
+# Description:
+#
+# This is one of the test cases presented in Popinet
+# \cite{popinet2003}.  We solve the Poisson equation in a square
+# domain with Neumann boundary conditions on all sides and the
+# right-hand-side:
+# $$
+# \nabla\cdot{\bf U}^{\star\star}(x,y) = -\pi^2(k^2+l^2)\sin(\pi kx)\sin(\pi ly)
+# $$
+# with $k = l = 3$. The exact solution of the Poisson equation with this source term is
+# $$
+# \phi(x,y)=\sin(\pi kx)\sin(\pi ly).
+# $$
+# Figure \ref{residual} illustrates the evolution of the maximum
+# residual as a function of CPU time. Figure \ref{rate}
+# illustrates the average residual reduction factor (per V-cycle). The
+# evolution of the norms of the error of the final solution as a
+# function of resolution is illustrated on Figure \ref{error}. The
+# corresponding order of convergence is given on Figure \ref{order}.
+#
+# \begin{figure}[htbp]
+# \caption{\label{residual}Evolution of the residual.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{residual.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{rate}Average reduction factor.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{rate.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Evolution of the error as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{error.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{order}Corresponding convergence order.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{order.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh poisson.sh poisson.gfs
+# Version: 0.8.0
+# Required files: poisson.sh res-7.ref error.ref order.ref
+# Generated files: residual.eps rate.eps error.eps order.eps
+#
+1 0 GfsPoisson GfsBox GfsGEdge {} {
+  Time { iend = 10 }
+  Refine LEVEL
+  ApproxProjectionParams { nrelax = 4 tolerance = 1e-30 }
+  Init {} {
+    Div = {
+      int k = 3, l = 3;
+      return -M_PI*M_PI*(k*k + l*l)*sin (M_PI*k*x)*sin (M_PI*l*y);
+    }
+  }
+  OutputTime { istep = 1 } {
+    awk '{print n++, $8}' > time
+  }
+  OutputProjectionStats { istep = 1 } {
+    awk '{
+      if ($1 == "niter:") printf ("%d ", $2);
+      if ($1 == "residual.infty:") print $3 " " $4;
+    }' > proj
+  }
+  OutputErrorNorm { start = end } {
+    awk '{print LEVEL " " $5 " " $7 " " $9}' >> error 
+  } { v = P } {
+    s = (sin (M_PI*3.*x)*sin (M_PI*3.*y))
+    unbiased = 1
+  }
+}
+GfsBox {}
diff --git a/test/poisson/poisson.sh b/test/poisson/poisson.sh
new file mode 100644
index 0000000..e33c74f
--- /dev/null
+++ b/test/poisson/poisson.sh
@@ -0,0 +1,78 @@
+if ! $donotrun; then
+    rm -f error
+    for level in 3 4 5 6 7 8; do
+	if ( sed "s/LEVEL/$level/g" < $1 | gerris2D - ) && join time proj > res-$level; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if awk '
+BEGIN { n = 0 }
+{
+  l[n] = $1; n1[n] = $2; n2[n] = $3; ni[n++] = $4;
+}
+END {
+  for (i = 1; i < n; i++)
+    print l[i] " " log(n1[i-1]/n1[i])/log(2.) " " log(n2[i-1]/n2[i])/log(2.) " " log(ni[i-1]/ni[i])/log(2.);
+}' < error > order; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'residual.eps'
+    set xlabel 'CPU time'
+    set ylabel 'Maximum residual'
+    set logscale y
+    plot 'res-7.ref' u 2:3 t 'ref' w lp, 'res-7' u 2:3 t '' w lp
+    set output 'rate.eps'
+    set xlabel 'V-cycle'
+    set ylabel 'Cumulative residual reduction factor'
+    unset logscale
+    plot 'res-7.ref' u 1:4 t 'ref' w lp, 'res-7' u 1:4 t '' w lp
+    set output 'error.eps'
+    set xlabel 'Level'
+    set ylabel 'Error norms'
+    set key
+    set logscale y
+    plot 'error.ref' u 1:2 t '1 (ref)' w lp, \
+         'error.ref' u 1:3 t '2 (ref)' w lp, \
+         'error.ref' u 1:4 t 'max (ref)' w lp, \
+         'error' u 1:2 t '1' w lp, \
+         'error' u 1:3 t '2' w lp, \
+         'error' u 1:4 t 'max' w lp
+    set output 'order.eps'
+    set xlabel 'Level'
+    set ylabel 'Order'
+    set key
+    unset logscale
+    set xtics 0,1
+    set ytics 0,1
+    set grid
+    plot [][0:3] 'order.ref' u 1:2 t '1 (ref)' w lp, \
+                 'order.ref' u 1:3 t '2 (ref)' w lp, \
+                 'order.ref' u 1:4 t 'max (ref)' w lp, \
+                 'order' u 1:2 t '1' w lp, \
+                 'order' u 1:3 t '2' w lp, \
+                 'order' u 1:4 t 'max' w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+c = Curve()
+for p in Curve('res-7.ref',2,3).l:
+    c.l.append((p[0]+0.1, p[1]))
+if (Curve('res-7',2,3) - c).max() > 1e-8 or\
+   (Curve('error',1,4) - Curve('error.ref',1,4)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/poisson/res-7.ref b/test/poisson/res-7.ref
new file mode 100644
index 0000000..1e1e821
--- /dev/null
+++ b/test/poisson/res-7.ref
@@ -0,0 +1,11 @@
+0 0 1.776e+02 0
+1 0.08 5.934e+00 30
+2 0.14 2.353e-01 27
+3 0.2 1.285e-02 24
+4 0.26 9.224e-04 21
+5 0.32 6.235e-05 20
+6 0.38 4.108e-06 19
+7 0.44 2.652e-07 18
+8 0.5 1.677e-08 18
+9 0.56 1.041e-09 18
+10 0.62 6.753e-11 17
diff --git a/test/reynolds/box/box.gfs b/test/reynolds/box/box.gfs
new file mode 100644
index 0000000..98a06b7
--- /dev/null
+++ b/test/reynolds/box/box.gfs
@@ -0,0 +1,58 @@
+# Title: Estimation of the numerical viscosity with refined box
+#
+# Description:
+#
+# Same as the previous test but with a refined box in the middle and four
+# modes of the exact Euler solution.
+#
+# \begin{figure}[htbp]
+# \caption{\label{divmax}Evolution of the maximum divergence.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{divmax.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{divL2}Evolution of the L2 norm of the divergence.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{divL2.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{kinetic}Evolution of the kinetic energy.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{kinetic.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{reynolds}Equivalent Reynolds number as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{reynolds.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../reynolds.sh box.gfs 4
+# Version: 0.6.4
+# Required files: ../reynolds.sh div5.ref div6.ref div7.ref reynolds.ref
+# Running time: 3 minutes
+# Generated files: divmax.eps reynolds.eps divL2.eps kinetic.eps
+#
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 2 }
+  Refine (x > 0.25 || x < -0.25 || y > 0.25 || y < -0.25 ? LEVEL : LEVEL + 1)
+  Init {} {
+    U = (- cos (8.*M_PI*x)*sin (8.*M_PI*y))
+    V = (sin (8.*M_PI*x)*cos (8.*M_PI*y))
+  }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  OutputScalarNorm { istep = 1 } divLEVEL { v = Divergence }
+  OutputScalarSum { istep = 1 } kineticLEVEL { v = Velocity2 }
+  OutputScalarSum { istep = 1 } stdout { v = Velocity2 }
+}
+GfsBox {}
+1 1 right
+1 1 top
diff --git a/test/reynolds/box/div5.ref b/test/reynolds/box/div5.ref
new file mode 100644
index 0000000..26cfd2b
--- /dev/null
+++ b/test/reynolds/box/div5.ref
@@ -0,0 +1,146 @@
+Divergence time: 0 first:  4.842e-02 second:  1.516e-01 infty:  6.945e-01
+Divergence time: 0.0129032 first:  1.531e+00 second:  2.091e+00 infty:  3.506e+00
+Divergence time: 0.0257232 first:  2.106e+00 second:  2.878e+00 infty:  4.958e+00
+Divergence time: 0.0385432 first:  2.309e+00 second:  3.144e+00 infty:  5.551e+00
+Divergence time: 0.0514475 first:  2.348e+00 second:  3.189e+00 infty:  5.707e+00
+Divergence time: 0.0643518 first:  2.308e+00 second:  3.128e+00 infty:  5.731e+00
+Divergence time: 0.0772561 first:  2.242e+00 second:  3.024e+00 infty:  5.558e+00
+Divergence time: 0.0901605 first:  2.162e+00 second:  2.906e+00 infty:  5.451e+00
+Divergence time: 0.103065 first:  2.076e+00 second:  2.789e+00 infty:  5.319e+00
+Divergence time: 0.115969 first:  1.994e+00 second:  2.678e+00 infty:  5.179e+00
+Divergence time: 0.128873 first:  1.922e+00 second:  2.574e+00 infty:  5.044e+00
+Divergence time: 0.141778 first:  1.854e+00 second:  2.478e+00 infty:  4.913e+00
+Divergence time: 0.154682 first:  1.793e+00 second:  2.388e+00 infty:  4.782e+00
+Divergence time: 0.167586 first:  1.737e+00 second:  2.305e+00 infty:  4.657e+00
+Divergence time: 0.180491 first:  1.685e+00 second:  2.229e+00 infty:  4.538e+00
+Divergence time: 0.193395 first:  1.634e+00 second:  2.157e+00 infty:  4.422e+00
+Divergence time: 0.206299 first:  1.584e+00 second:  2.091e+00 infty:  4.231e+00
+Divergence time: 0.219204 first:  1.535e+00 second:  2.027e+00 infty:  4.103e+00
+Divergence time: 0.232108 first:  1.492e+00 second:  1.967e+00 infty:  4.013e+00
+Divergence time: 0.245012 first:  1.453e+00 second:  1.909e+00 infty:  3.946e+00
+Divergence time: 0.257917 first:  1.417e+00 second:  1.854e+00 infty:  3.852e+00
+Divergence time: 0.270821 first:  1.383e+00 second:  1.802e+00 infty:  3.770e+00
+Divergence time: 0.283725 first:  1.348e+00 second:  1.751e+00 infty:  3.739e+00
+Divergence time: 0.29663 first:  1.313e+00 second:  1.701e+00 infty:  3.743e+00
+Divergence time: 0.309437 first:  1.274e+00 second:  1.647e+00 infty:  3.741e+00
+Divergence time: 0.322244 first:  1.240e+00 second:  1.599e+00 infty:  3.780e+00
+Divergence time: 0.335051 first:  1.209e+00 second:  1.554e+00 infty:  3.796e+00
+Divergence time: 0.347859 first:  1.181e+00 second:  1.511e+00 infty:  3.803e+00
+Divergence time: 0.360666 first:  1.152e+00 second:  1.469e+00 infty:  3.809e+00
+Divergence time: 0.373574 first:  1.127e+00 second:  1.433e+00 infty:  3.781e+00
+Divergence time: 0.386482 first:  1.097e+00 second:  1.395e+00 infty:  3.732e+00
+Divergence time: 0.399495 first:  1.068e+00 second:  1.360e+00 infty:  3.673e+00
+Divergence time: 0.412507 first:  1.036e+00 second:  1.321e+00 infty:  3.591e+00
+Divergence time: 0.425519 first:  1.002e+00 second:  1.284e+00 infty:  3.489e+00
+Divergence time: 0.438531 first:  9.699e-01 second:  1.245e+00 infty:  3.363e+00
+Divergence time: 0.451544 first:  9.403e-01 second:  1.206e+00 infty:  3.229e+00
+Divergence time: 0.464556 first:  9.129e-01 second:  1.168e+00 infty:  3.088e+00
+Divergence time: 0.477459 first:  8.805e-01 second:  1.124e+00 infty:  3.046e+00
+Divergence time: 0.490362 first:  8.511e-01 second:  1.083e+00 infty:  3.006e+00
+Divergence time: 0.503264 first:  8.216e-01 second:  1.045e+00 infty:  2.966e+00
+Divergence time: 0.516167 first:  7.923e-01 second:  1.010e+00 infty:  2.939e+00
+Divergence time: 0.529183 first:  7.666e-01 second:  9.793e-01 infty:  2.933e+00
+Divergence time: 0.5422 first:  7.395e-01 second:  9.480e-01 infty:  2.933e+00
+Divergence time: 0.555333 first:  7.146e-01 second:  9.185e-01 infty:  2.932e+00
+Divergence time: 0.568466 first:  6.884e-01 second:  8.871e-01 infty:  2.911e+00
+Divergence time: 0.581721 first:  6.629e-01 second:  8.575e-01 infty:  2.727e+00
+Divergence time: 0.595101 first:  6.423e-01 second:  8.328e-01 infty:  2.561e+00
+Divergence time: 0.60861 first:  6.233e-01 second:  8.092e-01 infty:  2.394e+00
+Divergence time: 0.622118 first:  6.041e-01 second:  7.859e-01 infty:  2.263e+00
+Divergence time: 0.635627 first:  5.853e-01 second:  7.643e-01 infty:  2.227e+00
+Divergence time: 0.649136 first:  5.713e-01 second:  7.432e-01 infty:  2.179e+00
+Divergence time: 0.662644 first:  5.590e-01 second:  7.229e-01 infty:  2.132e+00
+Divergence time: 0.676153 first:  5.507e-01 second:  7.060e-01 infty:  2.088e+00
+Divergence time: 0.689662 first:  5.386e-01 second:  6.881e-01 infty:  2.048e+00
+Divergence time: 0.70317 first:  5.268e-01 second:  6.706e-01 infty:  2.006e+00
+Divergence time: 0.716679 first:  5.136e-01 second:  6.510e-01 infty:  1.965e+00
+Divergence time: 0.730188 first:  5.029e-01 second:  6.331e-01 infty:  1.921e+00
+Divergence time: 0.743696 first:  4.925e-01 second:  6.166e-01 infty:  1.873e+00
+Divergence time: 0.757205 first:  4.815e-01 second:  6.010e-01 infty:  1.823e+00
+Divergence time: 0.770713 first:  4.718e-01 second:  5.872e-01 infty:  1.781e+00
+Divergence time: 0.784222 first:  4.608e-01 second:  5.750e-01 infty:  1.736e+00
+Divergence time: 0.797883 first:  4.527e-01 second:  5.670e-01 infty:  1.679e+00
+Divergence time: 0.811543 first:  4.424e-01 second:  5.576e-01 infty:  1.678e+00
+Divergence time: 0.825203 first:  4.321e-01 second:  5.480e-01 infty:  1.725e+00
+Divergence time: 0.838707 first:  4.207e-01 second:  5.352e-01 infty:  1.705e+00
+Divergence time: 0.85221 first:  4.096e-01 second:  5.224e-01 infty:  1.677e+00
+Divergence time: 0.865714 first:  4.000e-01 second:  5.109e-01 infty:  1.639e+00
+Divergence time: 0.879217 first:  3.912e-01 second:  5.003e-01 infty:  1.597e+00
+Divergence time: 0.89272 first:  3.816e-01 second:  4.895e-01 infty:  1.547e+00
+Divergence time: 0.906224 first:  3.734e-01 second:  4.799e-01 infty:  1.516e+00
+Divergence time: 0.919563 first:  3.647e-01 second:  4.680e-01 infty:  1.497e+00
+Divergence time: 0.932901 first:  3.564e-01 second:  4.567e-01 infty:  1.525e+00
+Divergence time: 0.94624 first:  3.483e-01 second:  4.457e-01 infty:  1.504e+00
+Divergence time: 0.959579 first:  3.408e-01 second:  4.341e-01 infty:  1.413e+00
+Divergence time: 0.972918 first:  3.333e-01 second:  4.230e-01 infty:  1.430e+00
+Divergence time: 0.986432 first:  3.268e-01 second:  4.167e-01 infty:  1.495e+00
+Divergence time: 0.999946 first:  3.197e-01 second:  4.096e-01 infty:  1.507e+00
+Divergence time: 1.01346 first:  3.117e-01 second:  4.021e-01 infty:  1.374e+00
+Divergence time: 1.02697 first:  3.018e-01 second:  3.948e-01 infty:  1.454e+00
+Divergence time: 1.04068 first:  2.971e-01 second:  3.905e-01 infty:  1.550e+00
+Divergence time: 1.05458 first:  2.922e-01 second:  3.872e-01 infty:  1.566e+00
+Divergence time: 1.06869 first:  2.876e-01 second:  3.829e-01 infty:  1.441e+00
+Divergence time: 1.0828 first:  2.796e-01 second:  3.764e-01 infty:  1.550e+00
+Divergence time: 1.09713 first:  2.742e-01 second:  3.727e-01 infty:  1.701e+00
+Divergence time: 1.11147 first:  2.688e-01 second:  3.672e-01 infty:  1.661e+00
+Divergence time: 1.1258 first:  2.638e-01 second:  3.613e-01 infty:  1.430e+00
+Divergence time: 1.14013 first:  2.579e-01 second:  3.566e-01 infty:  1.574e+00
+Divergence time: 1.15422 first:  2.509e-01 second:  3.505e-01 infty:  1.693e+00
+Divergence time: 1.16832 first:  2.465e-01 second:  3.475e-01 infty:  1.701e+00
+Divergence time: 1.18242 first:  2.429e-01 second:  3.446e-01 infty:  1.588e+00
+Divergence time: 1.19651 first:  2.407e-01 second:  3.423e-01 infty:  1.498e+00
+Divergence time: 1.21061 first:  2.406e-01 second:  3.420e-01 infty:  1.486e+00
+Divergence time: 1.22471 first:  2.386e-01 second:  3.420e-01 infty:  1.408e+00
+Divergence time: 1.2388 first:  2.370e-01 second:  3.420e-01 infty:  1.531e+00
+Divergence time: 1.2529 first:  2.358e-01 second:  3.416e-01 infty:  1.684e+00
+Divergence time: 1.26727 first:  2.355e-01 second:  3.432e-01 infty:  1.755e+00
+Divergence time: 1.28163 first:  2.337e-01 second:  3.422e-01 infty:  1.732e+00
+Divergence time: 1.296 first:  2.318e-01 second:  3.403e-01 infty:  1.855e+00
+Divergence time: 1.31037 first:  2.307e-01 second:  3.378e-01 infty:  1.879e+00
+Divergence time: 1.32416 first:  2.241e-01 second:  3.297e-01 infty:  1.753e+00
+Divergence time: 1.33741 first:  2.153e-01 second:  3.201e-01 infty:  1.712e+00
+Divergence time: 1.35066 first:  2.071e-01 second:  3.134e-01 infty:  1.867e+00
+Divergence time: 1.36365 first:  1.992e-01 second:  3.048e-01 infty:  1.912e+00
+Divergence time: 1.37664 first:  1.938e-01 second:  2.988e-01 infty:  1.852e+00
+Divergence time: 1.38962 first:  1.886e-01 second:  2.943e-01 infty:  1.754e+00
+Divergence time: 1.40289 first:  1.847e-01 second:  2.916e-01 infty:  1.742e+00
+Divergence time: 1.41587 first:  1.801e-01 second:  2.843e-01 infty:  1.653e+00
+Divergence time: 1.42885 first:  1.766e-01 second:  2.759e-01 infty:  1.510e+00
+Divergence time: 1.44183 first:  1.734e-01 second:  2.657e-01 infty:  1.322e+00
+Divergence time: 1.45482 first:  1.688e-01 second:  2.548e-01 infty:  1.226e+00
+Divergence time: 1.4678 first:  1.649e-01 second:  2.444e-01 infty:  1.188e+00
+Divergence time: 1.48078 first:  1.608e-01 second:  2.364e-01 infty:  1.158e+00
+Divergence time: 1.49409 first:  1.595e-01 second:  2.325e-01 infty:  1.142e+00
+Divergence time: 1.5074 first:  1.577e-01 second:  2.277e-01 infty:  1.110e+00
+Divergence time: 1.52072 first:  1.568e-01 second:  2.230e-01 infty:  1.041e+00
+Divergence time: 1.53403 first:  1.540e-01 second:  2.171e-01 infty:  1.036e+00
+Divergence time: 1.54774 first:  1.518e-01 second:  2.129e-01 infty:  9.428e-01
+Divergence time: 1.56187 first:  1.500e-01 second:  2.084e-01 infty:  1.027e+00
+Divergence time: 1.57647 first:  1.485e-01 second:  2.040e-01 infty:  1.061e+00
+Divergence time: 1.5916 first:  1.458e-01 second:  1.991e-01 infty:  1.001e+00
+Divergence time: 1.60672 first:  1.398e-01 second:  1.927e-01 infty:  9.824e-01
+Divergence time: 1.62246 first:  1.382e-01 second:  1.896e-01 infty:  9.460e-01
+Divergence time: 1.63819 first:  1.353e-01 second:  1.856e-01 infty:  8.732e-01
+Divergence time: 1.65463 first:  1.325e-01 second:  1.847e-01 infty:  8.812e-01
+Divergence time: 1.67108 first:  1.305e-01 second:  1.826e-01 infty:  8.741e-01
+Divergence time: 1.68753 first:  1.285e-01 second:  1.798e-01 infty:  8.311e-01
+Divergence time: 1.70397 first:  1.254e-01 second:  1.760e-01 infty:  7.598e-01
+Divergence time: 1.72042 first:  1.223e-01 second:  1.717e-01 infty:  7.004e-01
+Divergence time: 1.73686 first:  1.192e-01 second:  1.675e-01 infty:  7.853e-01
+Divergence time: 1.75331 first:  1.164e-01 second:  1.634e-01 infty:  8.596e-01
+Divergence time: 1.76976 first:  1.132e-01 second:  1.597e-01 infty:  9.083e-01
+Divergence time: 1.7862 first:  1.116e-01 second:  1.573e-01 infty:  9.438e-01
+Divergence time: 1.80265 first:  1.103e-01 second:  1.559e-01 infty:  9.641e-01
+Divergence time: 1.81909 first:  1.080e-01 second:  1.543e-01 infty:  9.673e-01
+Divergence time: 1.83554 first:  1.056e-01 second:  1.516e-01 infty:  9.510e-01
+Divergence time: 1.85049 first:  9.968e-02 second:  1.428e-01 infty:  8.940e-01
+Divergence time: 1.86544 first:  9.636e-02 second:  1.357e-01 infty:  8.416e-01
+Divergence time: 1.88039 first:  9.327e-02 second:  1.301e-01 infty:  7.942e-01
+Divergence time: 1.89534 first:  9.068e-02 second:  1.255e-01 infty:  7.300e-01
+Divergence time: 1.91029 first:  8.824e-02 second:  1.223e-01 infty:  6.528e-01
+Divergence time: 1.92525 first:  8.609e-02 second:  1.199e-01 infty:  5.685e-01
+Divergence time: 1.9402 first:  8.442e-02 second:  1.175e-01 infty:  5.166e-01
+Divergence time: 1.95515 first:  8.243e-02 second:  1.142e-01 infty:  5.198e-01
+Divergence time: 1.9701 first:  7.993e-02 second:  1.101e-01 infty:  4.725e-01
+Divergence time: 1.98505 first:  7.739e-02 second:  1.063e-01 infty:  4.051e-01
+Divergence time: 2 first:  7.543e-02 second:  1.030e-01 infty:  4.070e-01
diff --git a/test/reynolds/box/div6.ref b/test/reynolds/box/div6.ref
new file mode 100644
index 0000000..6890b15
--- /dev/null
+++ b/test/reynolds/box/div6.ref
@@ -0,0 +1,368 @@
+Divergence time: 0 first:  1.295e-02 second:  6.223e-02 infty:  4.398e-01
+Divergence time: 0.00628931 first:  3.487e-01 second:  4.579e-01 infty:  1.086e+00
+Divergence time: 0.0125786 first:  3.943e-01 second:  5.213e-01 infty:  1.310e+00
+Divergence time: 0.0188679 first:  4.001e-01 second:  5.311e-01 infty:  1.395e+00
+Divergence time: 0.0251572 first:  4.008e-01 second:  5.331e-01 infty:  1.436e+00
+Divergence time: 0.0314465 first:  4.010e-01 second:  5.335e-01 infty:  1.474e+00
+Divergence time: 0.0377358 first:  4.013e-01 second:  5.336e-01 infty:  1.492e+00
+Divergence time: 0.0440252 first:  4.015e-01 second:  5.334e-01 infty:  1.513e+00
+Divergence time: 0.0503145 first:  4.013e-01 second:  5.330e-01 infty:  1.522e+00
+Divergence time: 0.0566038 first:  4.009e-01 second:  5.324e-01 infty:  1.538e+00
+Divergence time: 0.0628931 first:  4.003e-01 second:  5.317e-01 infty:  1.535e+00
+Divergence time: 0.0691824 first:  4.000e-01 second:  5.311e-01 infty:  1.532e+00
+Divergence time: 0.0754717 first:  3.999e-01 second:  5.304e-01 infty:  1.531e+00
+Divergence time: 0.081761 first:  3.998e-01 second:  5.298e-01 infty:  1.531e+00
+Divergence time: 0.0880503 first:  3.999e-01 second:  5.292e-01 infty:  1.531e+00
+Divergence time: 0.0943396 first:  4.000e-01 second:  5.286e-01 infty:  1.520e+00
+Divergence time: 0.100629 first:  4.000e-01 second:  5.280e-01 infty:  1.520e+00
+Divergence time: 0.106918 first:  4.004e-01 second:  5.275e-01 infty:  1.522e+00
+Divergence time: 0.113208 first:  4.004e-01 second:  5.270e-01 infty:  1.524e+00
+Divergence time: 0.119497 first:  4.003e-01 second:  5.264e-01 infty:  1.529e+00
+Divergence time: 0.125786 first:  4.002e-01 second:  5.259e-01 infty:  1.534e+00
+Divergence time: 0.132075 first:  4.000e-01 second:  5.253e-01 infty:  1.541e+00
+Divergence time: 0.138365 first:  3.999e-01 second:  5.246e-01 infty:  1.547e+00
+Divergence time: 0.144654 first:  3.996e-01 second:  5.240e-01 infty:  1.552e+00
+Divergence time: 0.150943 first:  3.994e-01 second:  5.234e-01 infty:  1.556e+00
+Divergence time: 0.157233 first:  3.993e-01 second:  5.228e-01 infty:  1.561e+00
+Divergence time: 0.163522 first:  3.992e-01 second:  5.222e-01 infty:  1.563e+00
+Divergence time: 0.169811 first:  3.991e-01 second:  5.215e-01 infty:  1.566e+00
+Divergence time: 0.176101 first:  3.987e-01 second:  5.208e-01 infty:  1.568e+00
+Divergence time: 0.18239 first:  3.984e-01 second:  5.201e-01 infty:  1.570e+00
+Divergence time: 0.188679 first:  3.983e-01 second:  5.194e-01 infty:  1.572e+00
+Divergence time: 0.194969 first:  3.979e-01 second:  5.187e-01 infty:  1.574e+00
+Divergence time: 0.201258 first:  3.978e-01 second:  5.181e-01 infty:  1.572e+00
+Divergence time: 0.207547 first:  3.974e-01 second:  5.173e-01 infty:  1.573e+00
+Divergence time: 0.213836 first:  3.970e-01 second:  5.166e-01 infty:  1.577e+00
+Divergence time: 0.220126 first:  3.967e-01 second:  5.159e-01 infty:  1.583e+00
+Divergence time: 0.226393 first:  3.953e-01 second:  5.138e-01 infty:  1.585e+00
+Divergence time: 0.23266 first:  3.947e-01 second:  5.128e-01 infty:  1.590e+00
+Divergence time: 0.238927 first:  3.941e-01 second:  5.120e-01 infty:  1.595e+00
+Divergence time: 0.245217 first:  3.946e-01 second:  5.126e-01 infty:  1.605e+00
+Divergence time: 0.251506 first:  3.943e-01 second:  5.120e-01 infty:  1.611e+00
+Divergence time: 0.257796 first:  3.937e-01 second:  5.112e-01 infty:  1.615e+00
+Divergence time: 0.264085 first:  3.930e-01 second:  5.103e-01 infty:  1.619e+00
+Divergence time: 0.270375 first:  3.923e-01 second:  5.095e-01 infty:  1.623e+00
+Divergence time: 0.276665 first:  3.916e-01 second:  5.086e-01 infty:  1.626e+00
+Divergence time: 0.282954 first:  3.910e-01 second:  5.078e-01 infty:  1.639e+00
+Divergence time: 0.289244 first:  3.903e-01 second:  5.069e-01 infty:  1.648e+00
+Divergence time: 0.295533 first:  3.895e-01 second:  5.060e-01 infty:  1.654e+00
+Divergence time: 0.301823 first:  3.888e-01 second:  5.051e-01 infty:  1.657e+00
+Divergence time: 0.308112 first:  3.882e-01 second:  5.043e-01 infty:  1.658e+00
+Divergence time: 0.314402 first:  3.876e-01 second:  5.034e-01 infty:  1.659e+00
+Divergence time: 0.320691 first:  3.870e-01 second:  5.025e-01 infty:  1.658e+00
+Divergence time: 0.326981 first:  3.863e-01 second:  5.016e-01 infty:  1.657e+00
+Divergence time: 0.33327 first:  3.857e-01 second:  5.008e-01 infty:  1.664e+00
+Divergence time: 0.33956 first:  3.851e-01 second:  4.999e-01 infty:  1.672e+00
+Divergence time: 0.34585 first:  3.845e-01 second:  4.990e-01 infty:  1.675e+00
+Divergence time: 0.352139 first:  3.839e-01 second:  4.982e-01 infty:  1.675e+00
+Divergence time: 0.358429 first:  3.833e-01 second:  4.973e-01 infty:  1.673e+00
+Divergence time: 0.364718 first:  3.827e-01 second:  4.965e-01 infty:  1.671e+00
+Divergence time: 0.371008 first:  3.821e-01 second:  4.956e-01 infty:  1.667e+00
+Divergence time: 0.377297 first:  3.814e-01 second:  4.948e-01 infty:  1.685e+00
+Divergence time: 0.383563 first:  3.796e-01 second:  4.923e-01 infty:  1.703e+00
+Divergence time: 0.389828 first:  3.788e-01 second:  4.912e-01 infty:  1.716e+00
+Divergence time: 0.396093 first:  3.780e-01 second:  4.903e-01 infty:  1.725e+00
+Divergence time: 0.402358 first:  3.774e-01 second:  4.894e-01 infty:  1.730e+00
+Divergence time: 0.408624 first:  3.765e-01 second:  4.884e-01 infty:  1.731e+00
+Divergence time: 0.414889 first:  3.758e-01 second:  4.875e-01 infty:  1.730e+00
+Divergence time: 0.421154 first:  3.749e-01 second:  4.866e-01 infty:  1.728e+00
+Divergence time: 0.427419 first:  3.741e-01 second:  4.856e-01 infty:  1.724e+00
+Divergence time: 0.433685 first:  3.734e-01 second:  4.846e-01 infty:  1.717e+00
+Divergence time: 0.43995 first:  3.725e-01 second:  4.836e-01 infty:  1.711e+00
+Divergence time: 0.446215 first:  3.716e-01 second:  4.825e-01 infty:  1.625e+00
+Divergence time: 0.45248 first:  3.708e-01 second:  4.814e-01 infty:  1.605e+00
+Divergence time: 0.458746 first:  3.700e-01 second:  4.804e-01 infty:  1.613e+00
+Divergence time: 0.464986 first:  3.680e-01 second:  4.779e-01 infty:  1.611e+00
+Divergence time: 0.471225 first:  3.670e-01 second:  4.766e-01 infty:  1.596e+00
+Divergence time: 0.477465 first:  3.661e-01 second:  4.756e-01 infty:  1.597e+00
+Divergence time: 0.483705 first:  3.652e-01 second:  4.745e-01 infty:  1.600e+00
+Divergence time: 0.489945 first:  3.642e-01 second:  4.734e-01 infty:  1.606e+00
+Divergence time: 0.496185 first:  3.633e-01 second:  4.723e-01 infty:  1.610e+00
+Divergence time: 0.502425 first:  3.624e-01 second:  4.712e-01 infty:  1.613e+00
+Divergence time: 0.508639 first:  3.604e-01 second:  4.686e-01 infty:  1.610e+00
+Divergence time: 0.514853 first:  3.592e-01 second:  4.671e-01 infty:  1.601e+00
+Divergence time: 0.521067 first:  3.583e-01 second:  4.659e-01 infty:  1.608e+00
+Divergence time: 0.527281 first:  3.575e-01 second:  4.647e-01 infty:  1.610e+00
+Divergence time: 0.533495 first:  3.567e-01 second:  4.636e-01 infty:  1.611e+00
+Divergence time: 0.539709 first:  3.560e-01 second:  4.625e-01 infty:  1.612e+00
+Divergence time: 0.545923 first:  3.553e-01 second:  4.614e-01 infty:  1.614e+00
+Divergence time: 0.552111 first:  3.533e-01 second:  4.587e-01 infty:  1.611e+00
+Divergence time: 0.558298 first:  3.522e-01 second:  4.573e-01 infty:  1.610e+00
+Divergence time: 0.564486 first:  3.513e-01 second:  4.561e-01 infty:  1.608e+00
+Divergence time: 0.570673 first:  3.504e-01 second:  4.548e-01 infty:  1.605e+00
+Divergence time: 0.576861 first:  3.494e-01 second:  4.536e-01 infty:  1.601e+00
+Divergence time: 0.583022 first:  3.473e-01 second:  4.508e-01 infty:  1.590e+00
+Divergence time: 0.589182 first:  3.461e-01 second:  4.494e-01 infty:  1.583e+00
+Divergence time: 0.595343 first:  3.449e-01 second:  4.481e-01 infty:  1.563e+00
+Divergence time: 0.601504 first:  3.438e-01 second:  4.468e-01 infty:  1.564e+00
+Divergence time: 0.607665 first:  3.427e-01 second:  4.455e-01 infty:  1.570e+00
+Divergence time: 0.613798 first:  3.403e-01 second:  4.427e-01 infty:  1.571e+00
+Divergence time: 0.619932 first:  3.388e-01 second:  4.412e-01 infty:  1.583e+00
+Divergence time: 0.626066 first:  3.374e-01 second:  4.398e-01 infty:  1.602e+00
+Divergence time: 0.632199 first:  3.360e-01 second:  4.384e-01 infty:  1.634e+00
+Divergence time: 0.638305 first:  3.336e-01 second:  4.355e-01 infty:  1.635e+00
+Divergence time: 0.644412 first:  3.322e-01 second:  4.340e-01 infty:  1.649e+00
+Divergence time: 0.650491 first:  3.300e-01 second:  4.310e-01 infty:  1.660e+00
+Divergence time: 0.656569 first:  3.288e-01 second:  4.294e-01 infty:  1.671e+00
+Divergence time: 0.662621 first:  3.265e-01 second:  4.265e-01 infty:  1.673e+00
+Divergence time: 0.668672 first:  3.254e-01 second:  4.249e-01 infty:  1.674e+00
+Divergence time: 0.674697 first:  3.232e-01 second:  4.219e-01 infty:  1.666e+00
+Divergence time: 0.680721 first:  3.222e-01 second:  4.203e-01 infty:  1.666e+00
+Divergence time: 0.686717 first:  3.201e-01 second:  4.173e-01 infty:  1.659e+00
+Divergence time: 0.692687 first:  3.180e-01 second:  4.142e-01 infty:  1.675e+00
+Divergence time: 0.698656 first:  3.169e-01 second:  4.125e-01 infty:  1.691e+00
+Divergence time: 0.704599 first:  3.147e-01 second:  4.096e-01 infty:  1.698e+00
+Divergence time: 0.710541 first:  3.134e-01 second:  4.078e-01 infty:  1.708e+00
+Divergence time: 0.716456 first:  3.112e-01 second:  4.049e-01 infty:  1.717e+00
+Divergence time: 0.722371 first:  3.100e-01 second:  4.032e-01 infty:  1.726e+00
+Divergence time: 0.728258 first:  3.078e-01 second:  4.002e-01 infty:  1.728e+00
+Divergence time: 0.734146 first:  3.066e-01 second:  3.985e-01 infty:  1.735e+00
+Divergence time: 0.740006 first:  3.045e-01 second:  3.956e-01 infty:  1.737e+00
+Divergence time: 0.74584 first:  3.021e-01 second:  3.926e-01 infty:  1.719e+00
+Divergence time: 0.751646 first:  2.997e-01 second:  3.895e-01 infty:  1.707e+00
+Divergence time: 0.757452 first:  2.983e-01 second:  3.879e-01 infty:  1.704e+00
+Divergence time: 0.763232 first:  2.959e-01 second:  3.851e-01 infty:  1.699e+00
+Divergence time: 0.768984 first:  2.935e-01 second:  3.822e-01 infty:  1.711e+00
+Divergence time: 0.77471 first:  2.911e-01 second:  3.793e-01 infty:  1.720e+00
+Divergence time: 0.780409 first:  2.887e-01 second:  3.765e-01 infty:  1.720e+00
+Divergence time: 0.786108 first:  2.874e-01 second:  3.750e-01 infty:  1.717e+00
+Divergence time: 0.79178 first:  2.852e-01 second:  3.725e-01 infty:  1.704e+00
+Divergence time: 0.797426 first:  2.829e-01 second:  3.697e-01 infty:  1.686e+00
+Divergence time: 0.803046 first:  2.806e-01 second:  3.669e-01 infty:  1.660e+00
+Divergence time: 0.808665 first:  2.793e-01 second:  3.654e-01 infty:  1.630e+00
+Divergence time: 0.814258 first:  2.771e-01 second:  3.629e-01 infty:  1.597e+00
+Divergence time: 0.819825 first:  2.750e-01 second:  3.603e-01 infty:  1.561e+00
+Divergence time: 0.825392 first:  2.738e-01 second:  3.588e-01 infty:  1.541e+00
+Divergence time: 0.830959 first:  2.725e-01 second:  3.575e-01 infty:  1.527e+00
+Divergence time: 0.836526 first:  2.715e-01 second:  3.563e-01 infty:  1.509e+00
+Divergence time: 0.842092 first:  2.704e-01 second:  3.552e-01 infty:  1.486e+00
+Divergence time: 0.847659 first:  2.694e-01 second:  3.540e-01 infty:  1.371e+00
+Divergence time: 0.853226 first:  2.682e-01 second:  3.528e-01 infty:  1.378e+00
+Divergence time: 0.858793 first:  2.670e-01 second:  3.516e-01 infty:  1.383e+00
+Divergence time: 0.864387 first:  2.668e-01 second:  3.517e-01 infty:  1.390e+00
+Divergence time: 0.869981 first:  2.659e-01 second:  3.507e-01 infty:  1.403e+00
+Divergence time: 0.875603 first:  2.657e-01 second:  3.506e-01 infty:  1.429e+00
+Divergence time: 0.881225 first:  2.646e-01 second:  3.495e-01 infty:  1.462e+00
+Divergence time: 0.886876 first:  2.642e-01 second:  3.495e-01 infty:  1.499e+00
+Divergence time: 0.892526 first:  2.629e-01 second:  3.483e-01 infty:  1.524e+00
+Divergence time: 0.898205 first:  2.624e-01 second:  3.482e-01 infty:  1.543e+00
+Divergence time: 0.903885 first:  2.611e-01 second:  3.469e-01 infty:  1.551e+00
+Divergence time: 0.909594 first:  2.606e-01 second:  3.468e-01 infty:  1.570e+00
+Divergence time: 0.915333 first:  2.604e-01 second:  3.469e-01 infty:  1.588e+00
+Divergence time: 0.921072 first:  2.592e-01 second:  3.456e-01 infty:  1.595e+00
+Divergence time: 0.926841 first:  2.588e-01 second:  3.453e-01 infty:  1.603e+00
+Divergence time: 0.932642 first:  2.586e-01 second:  3.453e-01 infty:  1.608e+00
+Divergence time: 0.938475 first:  2.584e-01 second:  3.451e-01 infty:  1.642e+00
+Divergence time: 0.944307 first:  2.571e-01 second:  3.434e-01 infty:  1.676e+00
+Divergence time: 0.950172 first:  2.565e-01 second:  3.429e-01 infty:  1.708e+00
+Divergence time: 0.95607 first:  2.561e-01 second:  3.426e-01 infty:  1.733e+00
+Divergence time: 0.961968 first:  2.546e-01 second:  3.409e-01 infty:  1.746e+00
+Divergence time: 0.967833 first:  2.520e-01 second:  3.375e-01 infty:  1.785e+00
+Divergence time: 0.973631 first:  2.481e-01 second:  3.325e-01 infty:  1.784e+00
+Divergence time: 0.979365 first:  2.439e-01 second:  3.274e-01 infty:  1.760e+00
+Divergence time: 0.985067 first:  2.406e-01 second:  3.235e-01 infty:  1.728e+00
+Divergence time: 0.990706 first:  2.369e-01 second:  3.187e-01 infty:  1.687e+00
+Divergence time: 0.996282 first:  2.333e-01 second:  3.141e-01 infty:  1.649e+00
+Divergence time: 1.00183 first:  2.305e-01 second:  3.108e-01 infty:  1.612e+00
+Divergence time: 1.00731 first:  2.271e-01 second:  3.068e-01 infty:  1.572e+00
+Divergence time: 1.01277 first:  2.246e-01 second:  3.038e-01 infty:  1.534e+00
+Divergence time: 1.01819 first:  2.222e-01 second:  3.010e-01 infty:  1.496e+00
+Divergence time: 1.02359 first:  2.198e-01 second:  2.984e-01 infty:  1.476e+00
+Divergence time: 1.02898 first:  2.185e-01 second:  2.970e-01 infty:  1.455e+00
+Divergence time: 1.03434 first:  2.168e-01 second:  2.947e-01 infty:  1.409e+00
+Divergence time: 1.03971 first:  2.159e-01 second:  2.932e-01 infty:  1.363e+00
+Divergence time: 1.04507 first:  2.150e-01 second:  2.918e-01 infty:  1.383e+00
+Divergence time: 1.05044 first:  2.142e-01 second:  2.907e-01 infty:  1.381e+00
+Divergence time: 1.0558 first:  2.132e-01 second:  2.898e-01 infty:  1.402e+00
+Divergence time: 1.0612 first:  2.132e-01 second:  2.901e-01 infty:  1.421e+00
+Divergence time: 1.06659 first:  2.124e-01 second:  2.896e-01 infty:  1.419e+00
+Divergence time: 1.07196 first:  2.111e-01 second:  2.881e-01 infty:  1.395e+00
+Divergence time: 1.07732 first:  2.106e-01 second:  2.873e-01 infty:  1.364e+00
+Divergence time: 1.08269 first:  2.101e-01 second:  2.867e-01 infty:  1.380e+00
+Divergence time: 1.08802 first:  2.087e-01 second:  2.852e-01 infty:  1.431e+00
+Divergence time: 1.09332 first:  2.070e-01 second:  2.835e-01 infty:  1.478e+00
+Divergence time: 1.09856 first:  2.045e-01 second:  2.807e-01 infty:  1.507e+00
+Divergence time: 1.10377 first:  2.028e-01 second:  2.790e-01 infty:  1.511e+00
+Divergence time: 1.10895 first:  2.016e-01 second:  2.775e-01 infty:  1.456e+00
+Divergence time: 1.11411 first:  2.008e-01 second:  2.763e-01 infty:  1.493e+00
+Divergence time: 1.11923 first:  2.000e-01 second:  2.752e-01 infty:  1.537e+00
+Divergence time: 1.12432 first:  1.992e-01 second:  2.744e-01 infty:  1.496e+00
+Divergence time: 1.12935 first:  1.976e-01 second:  2.727e-01 infty:  1.452e+00
+Divergence time: 1.13433 first:  1.958e-01 second:  2.710e-01 infty:  1.410e+00
+Divergence time: 1.13927 first:  1.946e-01 second:  2.702e-01 infty:  1.486e+00
+Divergence time: 1.14416 first:  1.929e-01 second:  2.688e-01 infty:  1.550e+00
+Divergence time: 1.149 first:  1.909e-01 second:  2.671e-01 infty:  1.667e+00
+Divergence time: 1.15381 first:  1.897e-01 second:  2.665e-01 infty:  1.770e+00
+Divergence time: 1.15856 first:  1.878e-01 second:  2.653e-01 infty:  1.863e+00
+Divergence time: 1.16329 first:  1.863e-01 second:  2.646e-01 infty:  1.929e+00
+Divergence time: 1.16799 first:  1.851e-01 second:  2.636e-01 infty:  1.930e+00
+Divergence time: 1.17266 first:  1.838e-01 second:  2.625e-01 infty:  1.907e+00
+Divergence time: 1.17728 first:  1.820e-01 second:  2.606e-01 infty:  1.861e+00
+Divergence time: 1.18188 first:  1.805e-01 second:  2.594e-01 infty:  1.801e+00
+Divergence time: 1.18645 first:  1.790e-01 second:  2.581e-01 infty:  1.733e+00
+Divergence time: 1.19102 first:  1.784e-01 second:  2.576e-01 infty:  1.663e+00
+Divergence time: 1.19557 first:  1.773e-01 second:  2.562e-01 infty:  1.590e+00
+Divergence time: 1.20008 first:  1.758e-01 second:  2.545e-01 infty:  1.519e+00
+Divergence time: 1.20458 first:  1.743e-01 second:  2.528e-01 infty:  1.454e+00
+Divergence time: 1.20905 first:  1.729e-01 second:  2.510e-01 infty:  1.444e+00
+Divergence time: 1.21352 first:  1.720e-01 second:  2.499e-01 infty:  1.450e+00
+Divergence time: 1.21796 first:  1.710e-01 second:  2.486e-01 infty:  1.448e+00
+Divergence time: 1.22238 first:  1.701e-01 second:  2.472e-01 infty:  1.441e+00
+Divergence time: 1.2268 first:  1.694e-01 second:  2.466e-01 infty:  1.551e+00
+Divergence time: 1.23119 first:  1.682e-01 second:  2.455e-01 infty:  1.594e+00
+Divergence time: 1.23556 first:  1.672e-01 second:  2.444e-01 infty:  1.598e+00
+Divergence time: 1.23993 first:  1.667e-01 second:  2.440e-01 infty:  1.587e+00
+Divergence time: 1.24427 first:  1.656e-01 second:  2.430e-01 infty:  1.564e+00
+Divergence time: 1.24861 first:  1.652e-01 second:  2.427e-01 infty:  1.536e+00
+Divergence time: 1.25293 first:  1.642e-01 second:  2.419e-01 infty:  1.503e+00
+Divergence time: 1.25722 first:  1.629e-01 second:  2.409e-01 infty:  1.466e+00
+Divergence time: 1.26152 first:  1.621e-01 second:  2.406e-01 infty:  1.476e+00
+Divergence time: 1.26579 first:  1.608e-01 second:  2.396e-01 infty:  1.507e+00
+Divergence time: 1.27005 first:  1.598e-01 second:  2.390e-01 infty:  1.533e+00
+Divergence time: 1.2743 first:  1.587e-01 second:  2.380e-01 infty:  1.556e+00
+Divergence time: 1.27854 first:  1.580e-01 second:  2.374e-01 infty:  1.622e+00
+Divergence time: 1.28279 first:  1.573e-01 second:  2.368e-01 infty:  1.682e+00
+Divergence time: 1.28703 first:  1.568e-01 second:  2.363e-01 infty:  1.763e+00
+Divergence time: 1.29127 first:  1.564e-01 second:  2.359e-01 infty:  1.916e+00
+Divergence time: 1.29554 first:  1.564e-01 second:  2.362e-01 infty:  2.091e+00
+Divergence time: 1.29984 first:  1.567e-01 second:  2.367e-01 infty:  2.259e+00
+Divergence time: 1.30416 first:  1.572e-01 second:  2.375e-01 infty:  2.419e+00
+Divergence time: 1.30851 first:  1.577e-01 second:  2.384e-01 infty:  2.573e+00
+Divergence time: 1.31291 first:  1.585e-01 second:  2.399e-01 infty:  2.771e+00
+Divergence time: 1.31735 first:  1.589e-01 second:  2.411e-01 infty:  2.939e+00
+Divergence time: 1.32184 first:  1.597e-01 second:  2.429e-01 infty:  3.086e+00
+Divergence time: 1.32633 first:  1.595e-01 second:  2.432e-01 infty:  3.211e+00
+Divergence time: 1.33082 first:  1.590e-01 second:  2.428e-01 infty:  3.094e+00
+Divergence time: 1.33534 first:  1.586e-01 second:  2.430e-01 infty:  2.982e+00
+Divergence time: 1.33993 first:  1.587e-01 second:  2.440e-01 infty:  2.856e+00
+Divergence time: 1.34451 first:  1.582e-01 second:  2.437e-01 infty:  2.706e+00
+Divergence time: 1.34906 first:  1.571e-01 second:  2.424e-01 infty:  2.880e+00
+Divergence time: 1.35358 first:  1.553e-01 second:  2.407e-01 infty:  3.073e+00
+Divergence time: 1.35807 first:  1.536e-01 second:  2.389e-01 infty:  3.124e+00
+Divergence time: 1.36253 first:  1.519e-01 second:  2.372e-01 infty:  3.192e+00
+Divergence time: 1.36696 first:  1.506e-01 second:  2.355e-01 infty:  3.186e+00
+Divergence time: 1.37135 first:  1.491e-01 second:  2.329e-01 infty:  3.126e+00
+Divergence time: 1.37575 first:  1.482e-01 second:  2.311e-01 infty:  3.012e+00
+Divergence time: 1.38011 first:  1.470e-01 second:  2.290e-01 infty:  2.858e+00
+Divergence time: 1.38445 first:  1.458e-01 second:  2.269e-01 infty:  2.827e+00
+Divergence time: 1.38875 first:  1.441e-01 second:  2.245e-01 infty:  2.992e+00
+Divergence time: 1.39306 first:  1.430e-01 second:  2.230e-01 infty:  3.119e+00
+Divergence time: 1.39733 first:  1.416e-01 second:  2.210e-01 infty:  3.206e+00
+Divergence time: 1.40161 first:  1.405e-01 second:  2.195e-01 infty:  3.254e+00
+Divergence time: 1.40585 first:  1.391e-01 second:  2.175e-01 infty:  3.251e+00
+Divergence time: 1.41006 first:  1.377e-01 second:  2.154e-01 infty:  3.175e+00
+Divergence time: 1.41425 first:  1.362e-01 second:  2.130e-01 infty:  3.072e+00
+Divergence time: 1.4184 first:  1.346e-01 second:  2.107e-01 infty:  2.939e+00
+Divergence time: 1.42253 first:  1.329e-01 second:  2.084e-01 infty:  2.798e+00
+Divergence time: 1.42665 first:  1.318e-01 second:  2.068e-01 infty:  2.653e+00
+Divergence time: 1.43075 first:  1.305e-01 second:  2.049e-01 infty:  2.515e+00
+Divergence time: 1.43484 first:  1.297e-01 second:  2.035e-01 infty:  2.353e+00
+Divergence time: 1.43894 first:  1.289e-01 second:  2.024e-01 infty:  2.192e+00
+Divergence time: 1.44306 first:  1.287e-01 second:  2.015e-01 infty:  2.030e+00
+Divergence time: 1.44722 first:  1.286e-01 second:  2.011e-01 infty:  2.040e+00
+Divergence time: 1.45141 first:  1.288e-01 second:  2.010e-01 infty:  2.074e+00
+Divergence time: 1.45563 first:  1.288e-01 second:  2.009e-01 infty:  2.104e+00
+Divergence time: 1.45985 first:  1.282e-01 second:  1.997e-01 infty:  2.090e+00
+Divergence time: 1.46407 first:  1.272e-01 second:  1.980e-01 infty:  2.027e+00
+Divergence time: 1.46829 first:  1.260e-01 second:  1.961e-01 infty:  1.958e+00
+Divergence time: 1.47254 first:  1.254e-01 second:  1.947e-01 infty:  1.808e+00
+Divergence time: 1.47686 first:  1.256e-01 second:  1.942e-01 infty:  1.626e+00
+Divergence time: 1.48122 first:  1.257e-01 second:  1.935e-01 infty:  1.414e+00
+Divergence time: 1.48558 first:  1.252e-01 second:  1.923e-01 infty:  1.340e+00
+Divergence time: 1.48994 first:  1.247e-01 second:  1.914e-01 infty:  1.263e+00
+Divergence time: 1.49434 first:  1.245e-01 second:  1.916e-01 infty:  1.425e+00
+Divergence time: 1.49878 first:  1.244e-01 second:  1.922e-01 infty:  1.576e+00
+Divergence time: 1.50325 first:  1.241e-01 second:  1.923e-01 infty:  1.578e+00
+Divergence time: 1.50777 first:  1.238e-01 second:  1.919e-01 infty:  1.475e+00
+Divergence time: 1.51228 first:  1.230e-01 second:  1.905e-01 infty:  1.444e+00
+Divergence time: 1.51684 first:  1.225e-01 second:  1.891e-01 infty:  1.431e+00
+Divergence time: 1.52144 first:  1.221e-01 second:  1.880e-01 infty:  1.423e+00
+Divergence time: 1.52613 first:  1.225e-01 second:  1.876e-01 infty:  1.432e+00
+Divergence time: 1.53087 first:  1.229e-01 second:  1.868e-01 infty:  1.396e+00
+Divergence time: 1.53571 first:  1.233e-01 second:  1.865e-01 infty:  1.334e+00
+Divergence time: 1.5407 first:  1.244e-01 second:  1.873e-01 infty:  1.250e+00
+Divergence time: 1.5458 first:  1.253e-01 second:  1.876e-01 infty:  1.199e+00
+Divergence time: 1.55103 first:  1.264e-01 second:  1.882e-01 infty:  1.186e+00
+Divergence time: 1.55631 first:  1.270e-01 second:  1.882e-01 infty:  1.190e+00
+Divergence time: 1.56159 first:  1.271e-01 second:  1.873e-01 infty:  1.166e+00
+Divergence time: 1.56694 first:  1.275e-01 second:  1.870e-01 infty:  1.101e+00
+Divergence time: 1.57228 first:  1.271e-01 second:  1.859e-01 infty:  1.250e+00
+Divergence time: 1.57763 first:  1.264e-01 second:  1.843e-01 infty:  1.330e+00
+Divergence time: 1.58298 first:  1.255e-01 second:  1.825e-01 infty:  1.329e+00
+Divergence time: 1.58832 first:  1.245e-01 second:  1.804e-01 infty:  1.270e+00
+Divergence time: 1.59367 first:  1.234e-01 second:  1.785e-01 infty:  1.178e+00
+Divergence time: 1.59909 first:  1.231e-01 second:  1.778e-01 infty:  1.126e+00
+Divergence time: 1.6045 first:  1.222e-01 second:  1.763e-01 infty:  1.127e+00
+Divergence time: 1.60992 first:  1.213e-01 second:  1.748e-01 infty:  1.110e+00
+Divergence time: 1.61534 first:  1.202e-01 second:  1.731e-01 infty:  1.074e+00
+Divergence time: 1.62083 first:  1.202e-01 second:  1.729e-01 infty:  1.023e+00
+Divergence time: 1.62633 first:  1.199e-01 second:  1.722e-01 infty:  1.071e+00
+Divergence time: 1.63182 first:  1.195e-01 second:  1.718e-01 infty:  1.111e+00
+Divergence time: 1.6374 first:  1.200e-01 second:  1.729e-01 infty:  1.184e+00
+Divergence time: 1.64298 first:  1.203e-01 second:  1.735e-01 infty:  1.210e+00
+Divergence time: 1.64865 first:  1.217e-01 second:  1.755e-01 infty:  1.217e+00
+Divergence time: 1.65441 first:  1.235e-01 second:  1.783e-01 infty:  1.206e+00
+Divergence time: 1.66017 first:  1.244e-01 second:  1.802e-01 infty:  1.163e+00
+Divergence time: 1.66593 first:  1.248e-01 second:  1.817e-01 infty:  1.130e+00
+Divergence time: 1.67169 first:  1.248e-01 second:  1.830e-01 infty:  1.142e+00
+Divergence time: 1.67745 first:  1.244e-01 second:  1.838e-01 infty:  1.324e+00
+Divergence time: 1.68321 first:  1.244e-01 second:  1.843e-01 infty:  1.491e+00
+Divergence time: 1.68897 first:  1.245e-01 second:  1.844e-01 infty:  1.597e+00
+Divergence time: 1.69462 first:  1.231e-01 second:  1.827e-01 infty:  1.629e+00
+Divergence time: 1.70028 first:  1.222e-01 second:  1.818e-01 infty:  1.598e+00
+Divergence time: 1.70593 first:  1.214e-01 second:  1.810e-01 infty:  1.507e+00
+Divergence time: 1.71148 first:  1.196e-01 second:  1.789e-01 infty:  1.354e+00
+Divergence time: 1.71703 first:  1.187e-01 second:  1.774e-01 infty:  1.349e+00
+Divergence time: 1.72258 first:  1.178e-01 second:  1.761e-01 infty:  1.426e+00
+Divergence time: 1.72824 first:  1.181e-01 second:  1.763e-01 infty:  1.506e+00
+Divergence time: 1.7339 first:  1.177e-01 second:  1.755e-01 infty:  1.570e+00
+Divergence time: 1.73945 first:  1.155e-01 second:  1.727e-01 infty:  1.610e+00
+Divergence time: 1.74499 first:  1.143e-01 second:  1.709e-01 infty:  1.743e+00
+Divergence time: 1.75053 first:  1.134e-01 second:  1.694e-01 infty:  1.812e+00
+Divergence time: 1.75608 first:  1.125e-01 second:  1.678e-01 infty:  1.847e+00
+Divergence time: 1.76162 first:  1.118e-01 second:  1.662e-01 infty:  1.860e+00
+Divergence time: 1.76716 first:  1.109e-01 second:  1.643e-01 infty:  1.857e+00
+Divergence time: 1.77271 first:  1.099e-01 second:  1.623e-01 infty:  1.839e+00
+Divergence time: 1.77825 first:  1.090e-01 second:  1.604e-01 infty:  1.804e+00
+Divergence time: 1.78379 first:  1.080e-01 second:  1.585e-01 infty:  1.754e+00
+Divergence time: 1.78934 first:  1.072e-01 second:  1.565e-01 infty:  1.641e+00
+Divergence time: 1.79488 first:  1.063e-01 second:  1.545e-01 infty:  1.548e+00
+Divergence time: 1.80043 first:  1.055e-01 second:  1.527e-01 infty:  1.458e+00
+Divergence time: 1.80597 first:  1.049e-01 second:  1.509e-01 infty:  1.364e+00
+Divergence time: 1.81151 first:  1.039e-01 second:  1.493e-01 infty:  1.265e+00
+Divergence time: 1.81706 first:  1.029e-01 second:  1.477e-01 infty:  1.160e+00
+Divergence time: 1.8226 first:  1.020e-01 second:  1.464e-01 infty:  1.051e+00
+Divergence time: 1.82814 first:  1.012e-01 second:  1.452e-01 infty:  9.943e-01
+Divergence time: 1.83369 first:  1.002e-01 second:  1.440e-01 infty:  9.872e-01
+Divergence time: 1.83905 first:  9.774e-02 second:  1.407e-01 infty:  9.846e-01
+Divergence time: 1.84442 first:  9.634e-02 second:  1.389e-01 infty:  9.801e-01
+Divergence time: 1.84978 first:  9.525e-02 second:  1.375e-01 infty:  9.685e-01
+Divergence time: 1.85515 first:  9.400e-02 second:  1.363e-01 infty:  9.500e-01
+Divergence time: 1.86051 first:  9.289e-02 second:  1.351e-01 infty:  9.245e-01
+Divergence time: 1.86588 first:  9.224e-02 second:  1.341e-01 infty:  8.933e-01
+Divergence time: 1.87124 first:  9.156e-02 second:  1.330e-01 infty:  8.567e-01
+Divergence time: 1.87661 first:  9.087e-02 second:  1.320e-01 infty:  8.147e-01
+Divergence time: 1.88222 first:  9.208e-02 second:  1.335e-01 infty:  8.035e-01
+Divergence time: 1.88783 first:  9.182e-02 second:  1.332e-01 infty:  8.443e-01
+Divergence time: 1.89343 first:  9.129e-02 second:  1.324e-01 infty:  8.112e-01
+Divergence time: 1.89904 first:  9.062e-02 second:  1.312e-01 infty:  8.246e-01
+Divergence time: 1.90436 first:  8.734e-02 second:  1.268e-01 infty:  8.224e-01
+Divergence time: 1.90967 first:  8.550e-02 second:  1.244e-01 infty:  8.162e-01
+Divergence time: 1.91498 first:  8.414e-02 second:  1.224e-01 infty:  8.069e-01
+Divergence time: 1.9203 first:  8.306e-02 second:  1.206e-01 infty:  7.948e-01
+Divergence time: 1.92561 first:  8.202e-02 second:  1.186e-01 infty:  7.802e-01
+Divergence time: 1.93092 first:  8.089e-02 second:  1.167e-01 infty:  7.634e-01
+Divergence time: 1.93624 first:  7.979e-02 second:  1.148e-01 infty:  7.602e-01
+Divergence time: 1.94155 first:  7.860e-02 second:  1.130e-01 infty:  7.687e-01
+Divergence time: 1.94642 first:  7.446e-02 second:  1.074e-01 infty:  7.242e-01
+Divergence time: 1.95129 first:  7.278e-02 second:  1.049e-01 infty:  7.126e-01
+Divergence time: 1.95616 first:  7.179e-02 second:  1.034e-01 infty:  6.896e-01
+Divergence time: 1.96103 first:  7.094e-02 second:  1.020e-01 infty:  7.053e-01
+Divergence time: 1.9659 first:  7.016e-02 second:  1.008e-01 infty:  7.218e-01
+Divergence time: 1.97078 first:  6.935e-02 second:  9.987e-02 infty:  7.340e-01
+Divergence time: 1.97565 first:  6.852e-02 second:  9.916e-02 infty:  7.419e-01
+Divergence time: 1.98052 first:  6.784e-02 second:  9.840e-02 infty:  7.451e-01
+Divergence time: 1.98539 first:  6.729e-02 second:  9.783e-02 infty:  7.436e-01
+Divergence time: 1.99026 first:  6.688e-02 second:  9.735e-02 infty:  7.372e-01
+Divergence time: 1.99513 first:  6.647e-02 second:  9.692e-02 infty:  7.262e-01
+Divergence time: 2 first:  6.596e-02 second:  9.652e-02 infty:  7.113e-01
diff --git a/test/reynolds/box/div7.ref b/test/reynolds/box/div7.ref
new file mode 100644
index 0000000..4eb1d80
--- /dev/null
+++ b/test/reynolds/box/div7.ref
@@ -0,0 +1,773 @@
+Divergence time: 0 first:  3.233e-03 second:  2.273e-02 infty:  2.315e-01
+Divergence time: 0.00312989 first:  5.252e-02 second:  7.072e-02 infty:  3.612e-01
+Divergence time: 0.00625978 first:  5.490e-02 second:  7.368e-02 infty:  3.465e-01
+Divergence time: 0.00938967 first:  5.526e-02 second:  7.417e-02 infty:  3.260e-01
+Divergence time: 0.0125196 first:  5.542e-02 second:  7.453e-02 infty:  3.190e-01
+Divergence time: 0.0156495 first:  5.551e-02 second:  7.486e-02 infty:  3.170e-01
+Divergence time: 0.0187793 first:  5.565e-02 second:  7.523e-02 infty:  3.160e-01
+Divergence time: 0.0219092 first:  5.581e-02 second:  7.553e-02 infty:  3.140e-01
+Divergence time: 0.0250391 first:  5.585e-02 second:  7.575e-02 infty:  3.169e-01
+Divergence time: 0.028169 first:  5.590e-02 second:  7.594e-02 infty:  3.121e-01
+Divergence time: 0.0312989 first:  5.590e-02 second:  7.607e-02 infty:  3.289e-01
+Divergence time: 0.0344288 first:  5.596e-02 second:  7.619e-02 infty:  3.346e-01
+Divergence time: 0.0375587 first:  5.605e-02 second:  7.629e-02 infty:  3.301e-01
+Divergence time: 0.0406886 first:  5.609e-02 second:  7.639e-02 infty:  3.367e-01
+Divergence time: 0.0438185 first:  5.605e-02 second:  7.641e-02 infty:  3.493e-01
+Divergence time: 0.0469484 first:  5.605e-02 second:  7.642e-02 infty:  3.601e-01
+Divergence time: 0.0500732 first:  5.602e-02 second:  7.638e-02 infty:  3.556e-01
+Divergence time: 0.0532031 first:  5.611e-02 second:  7.647e-02 infty:  3.390e-01
+Divergence time: 0.056333 first:  5.615e-02 second:  7.653e-02 infty:  3.324e-01
+Divergence time: 0.0594629 first:  5.625e-02 second:  7.661e-02 infty:  3.308e-01
+Divergence time: 0.0625928 first:  5.628e-02 second:  7.665e-02 infty:  3.272e-01
+Divergence time: 0.0657227 first:  5.620e-02 second:  7.661e-02 infty:  3.251e-01
+Divergence time: 0.0688476 first:  5.613e-02 second:  7.654e-02 infty:  3.235e-01
+Divergence time: 0.0719724 first:  5.605e-02 second:  7.649e-02 infty:  3.227e-01
+Divergence time: 0.0750973 first:  5.599e-02 second:  7.647e-02 infty:  3.230e-01
+Divergence time: 0.0782221 first:  5.594e-02 second:  7.643e-02 infty:  3.234e-01
+Divergence time: 0.0813469 first:  5.585e-02 second:  7.640e-02 infty:  3.237e-01
+Divergence time: 0.0844718 first:  5.581e-02 second:  7.636e-02 infty:  3.236e-01
+Divergence time: 0.0875966 first:  5.584e-02 second:  7.635e-02 infty:  3.233e-01
+Divergence time: 0.0907215 first:  5.585e-02 second:  7.634e-02 infty:  3.235e-01
+Divergence time: 0.0938463 first:  5.586e-02 second:  7.632e-02 infty:  3.238e-01
+Divergence time: 0.0969712 first:  5.589e-02 second:  7.632e-02 infty:  3.241e-01
+Divergence time: 0.100096 first:  5.592e-02 second:  7.633e-02 infty:  3.244e-01
+Divergence time: 0.103221 first:  5.594e-02 second:  7.632e-02 infty:  3.263e-01
+Divergence time: 0.106346 first:  5.599e-02 second:  7.633e-02 infty:  3.302e-01
+Divergence time: 0.109471 first:  5.602e-02 second:  7.635e-02 infty:  3.316e-01
+Divergence time: 0.112595 first:  5.606e-02 second:  7.636e-02 infty:  3.308e-01
+Divergence time: 0.11572 first:  5.605e-02 second:  7.636e-02 infty:  3.290e-01
+Divergence time: 0.118845 first:  5.603e-02 second:  7.633e-02 infty:  3.268e-01
+Divergence time: 0.12197 first:  5.601e-02 second:  7.631e-02 infty:  3.248e-01
+Divergence time: 0.125095 first:  5.597e-02 second:  7.629e-02 infty:  3.230e-01
+Divergence time: 0.12822 first:  5.594e-02 second:  7.627e-02 infty:  3.222e-01
+Divergence time: 0.131344 first:  5.595e-02 second:  7.626e-02 infty:  3.220e-01
+Divergence time: 0.134469 first:  5.596e-02 second:  7.626e-02 infty:  3.218e-01
+Divergence time: 0.137594 first:  5.594e-02 second:  7.624e-02 infty:  3.216e-01
+Divergence time: 0.140719 first:  5.592e-02 second:  7.621e-02 infty:  3.214e-01
+Divergence time: 0.143844 first:  5.588e-02 second:  7.619e-02 infty:  3.212e-01
+Divergence time: 0.146969 first:  5.585e-02 second:  7.616e-02 infty:  3.209e-01
+Divergence time: 0.150093 first:  5.585e-02 second:  7.615e-02 infty:  3.207e-01
+Divergence time: 0.153218 first:  5.583e-02 second:  7.613e-02 infty:  3.205e-01
+Divergence time: 0.156343 first:  5.583e-02 second:  7.613e-02 infty:  3.203e-01
+Divergence time: 0.159468 first:  5.581e-02 second:  7.611e-02 infty:  3.201e-01
+Divergence time: 0.162593 first:  5.581e-02 second:  7.610e-02 infty:  3.200e-01
+Divergence time: 0.165718 first:  5.581e-02 second:  7.608e-02 infty:  3.200e-01
+Divergence time: 0.168843 first:  5.582e-02 second:  7.607e-02 infty:  3.244e-01
+Divergence time: 0.171967 first:  5.583e-02 second:  7.606e-02 infty:  3.284e-01
+Divergence time: 0.175092 first:  5.587e-02 second:  7.608e-02 infty:  3.297e-01
+Divergence time: 0.178217 first:  5.589e-02 second:  7.607e-02 infty:  3.290e-01
+Divergence time: 0.181342 first:  5.592e-02 second:  7.607e-02 infty:  3.271e-01
+Divergence time: 0.184467 first:  5.594e-02 second:  7.605e-02 infty:  3.250e-01
+Divergence time: 0.187592 first:  5.594e-02 second:  7.604e-02 infty:  3.229e-01
+Divergence time: 0.190716 first:  5.597e-02 second:  7.603e-02 infty:  3.213e-01
+Divergence time: 0.193841 first:  5.599e-02 second:  7.603e-02 infty:  3.200e-01
+Divergence time: 0.196966 first:  5.602e-02 second:  7.603e-02 infty:  3.190e-01
+Divergence time: 0.200091 first:  5.603e-02 second:  7.603e-02 infty:  3.187e-01
+Divergence time: 0.203216 first:  5.603e-02 second:  7.602e-02 infty:  3.187e-01
+Divergence time: 0.206341 first:  5.603e-02 second:  7.600e-02 infty:  3.188e-01
+Divergence time: 0.209465 first:  5.603e-02 second:  7.600e-02 infty:  3.188e-01
+Divergence time: 0.21259 first:  5.605e-02 second:  7.601e-02 infty:  3.189e-01
+Divergence time: 0.215715 first:  5.605e-02 second:  7.601e-02 infty:  3.190e-01
+Divergence time: 0.21884 first:  5.606e-02 second:  7.601e-02 infty:  3.191e-01
+Divergence time: 0.221965 first:  5.606e-02 second:  7.602e-02 infty:  3.193e-01
+Divergence time: 0.22509 first:  5.606e-02 second:  7.602e-02 infty:  3.195e-01
+Divergence time: 0.228215 first:  5.606e-02 second:  7.602e-02 infty:  3.255e-01
+Divergence time: 0.231339 first:  5.608e-02 second:  7.603e-02 infty:  3.454e-01
+Divergence time: 0.234464 first:  5.611e-02 second:  7.603e-02 infty:  3.558e-01
+Divergence time: 0.237589 first:  5.608e-02 second:  7.602e-02 infty:  3.609e-01
+Divergence time: 0.240714 first:  5.608e-02 second:  7.602e-02 infty:  3.630e-01
+Divergence time: 0.243839 first:  5.605e-02 second:  7.600e-02 infty:  3.637e-01
+Divergence time: 0.246964 first:  5.601e-02 second:  7.597e-02 infty:  3.644e-01
+Divergence time: 0.250088 first:  5.598e-02 second:  7.595e-02 infty:  3.644e-01
+Divergence time: 0.253213 first:  5.594e-02 second:  7.592e-02 infty:  3.641e-01
+Divergence time: 0.256338 first:  5.589e-02 second:  7.589e-02 infty:  3.645e-01
+Divergence time: 0.259463 first:  5.586e-02 second:  7.585e-02 infty:  3.653e-01
+Divergence time: 0.262588 first:  5.582e-02 second:  7.582e-02 infty:  3.747e-01
+Divergence time: 0.265707 first:  5.570e-02 second:  7.568e-02 infty:  3.769e-01
+Divergence time: 0.268826 first:  5.567e-02 second:  7.565e-02 infty:  3.732e-01
+Divergence time: 0.271945 first:  5.564e-02 second:  7.562e-02 infty:  3.663e-01
+Divergence time: 0.275065 first:  5.561e-02 second:  7.559e-02 infty:  3.604e-01
+Divergence time: 0.278184 first:  5.558e-02 second:  7.556e-02 infty:  3.562e-01
+Divergence time: 0.281303 first:  5.554e-02 second:  7.553e-02 infty:  3.535e-01
+Divergence time: 0.284422 first:  5.551e-02 second:  7.551e-02 infty:  3.520e-01
+Divergence time: 0.287542 first:  5.549e-02 second:  7.548e-02 infty:  3.512e-01
+Divergence time: 0.290661 first:  5.547e-02 second:  7.546e-02 infty:  3.509e-01
+Divergence time: 0.29378 first:  5.545e-02 second:  7.543e-02 infty:  3.509e-01
+Divergence time: 0.296899 first:  5.542e-02 second:  7.540e-02 infty:  3.510e-01
+Divergence time: 0.300019 first:  5.540e-02 second:  7.537e-02 infty:  3.510e-01
+Divergence time: 0.303138 first:  5.539e-02 second:  7.535e-02 infty:  3.511e-01
+Divergence time: 0.306257 first:  5.538e-02 second:  7.534e-02 infty:  3.512e-01
+Divergence time: 0.309376 first:  5.535e-02 second:  7.531e-02 infty:  3.412e-01
+Divergence time: 0.312495 first:  5.532e-02 second:  7.529e-02 infty:  3.378e-01
+Divergence time: 0.315615 first:  5.530e-02 second:  7.527e-02 infty:  3.457e-01
+Divergence time: 0.318734 first:  5.528e-02 second:  7.525e-02 infty:  3.579e-01
+Divergence time: 0.321853 first:  5.525e-02 second:  7.523e-02 infty:  3.641e-01
+Divergence time: 0.324972 first:  5.524e-02 second:  7.521e-02 infty:  3.669e-01
+Divergence time: 0.328092 first:  5.522e-02 second:  7.519e-02 infty:  3.800e-01
+Divergence time: 0.331211 first:  5.520e-02 second:  7.518e-02 infty:  3.767e-01
+Divergence time: 0.33433 first:  5.518e-02 second:  7.518e-02 infty:  3.699e-01
+Divergence time: 0.337449 first:  5.517e-02 second:  7.517e-02 infty:  3.803e-01
+Divergence time: 0.340569 first:  5.516e-02 second:  7.514e-02 infty:  3.813e-01
+Divergence time: 0.343688 first:  5.516e-02 second:  7.513e-02 infty:  3.778e-01
+Divergence time: 0.346807 first:  5.515e-02 second:  7.513e-02 infty:  3.708e-01
+Divergence time: 0.349926 first:  5.515e-02 second:  7.513e-02 infty:  3.647e-01
+Divergence time: 0.353046 first:  5.515e-02 second:  7.513e-02 infty:  3.503e-01
+Divergence time: 0.356165 first:  5.514e-02 second:  7.513e-02 infty:  3.439e-01
+Divergence time: 0.359284 first:  5.512e-02 second:  7.511e-02 infty:  3.402e-01
+Divergence time: 0.362403 first:  5.512e-02 second:  7.511e-02 infty:  3.380e-01
+Divergence time: 0.365522 first:  5.512e-02 second:  7.510e-02 infty:  3.343e-01
+Divergence time: 0.368642 first:  5.510e-02 second:  7.509e-02 infty:  3.335e-01
+Divergence time: 0.371761 first:  5.509e-02 second:  7.507e-02 infty:  3.491e-01
+Divergence time: 0.37488 first:  5.508e-02 second:  7.506e-02 infty:  3.605e-01
+Divergence time: 0.377999 first:  5.508e-02 second:  7.506e-02 infty:  3.659e-01
+Divergence time: 0.381119 first:  5.506e-02 second:  7.504e-02 infty:  3.681e-01
+Divergence time: 0.384238 first:  5.504e-02 second:  7.501e-02 infty:  3.810e-01
+Divergence time: 0.387357 first:  5.502e-02 second:  7.499e-02 infty:  3.772e-01
+Divergence time: 0.390476 first:  5.500e-02 second:  7.498e-02 infty:  3.699e-01
+Divergence time: 0.393596 first:  5.498e-02 second:  7.496e-02 infty:  3.651e-01
+Divergence time: 0.396715 first:  5.496e-02 second:  7.494e-02 infty:  3.671e-01
+Divergence time: 0.399834 first:  5.493e-02 second:  7.492e-02 infty:  3.797e-01
+Divergence time: 0.402953 first:  5.489e-02 second:  7.490e-02 infty:  3.760e-01
+Divergence time: 0.406072 first:  5.488e-02 second:  7.489e-02 infty:  3.688e-01
+Divergence time: 0.409192 first:  5.485e-02 second:  7.486e-02 infty:  3.526e-01
+Divergence time: 0.412311 first:  5.484e-02 second:  7.484e-02 infty:  3.446e-01
+Divergence time: 0.415424 first:  5.473e-02 second:  7.470e-02 infty:  3.398e-01
+Divergence time: 0.418537 first:  5.471e-02 second:  7.468e-02 infty:  3.346e-01
+Divergence time: 0.42165 first:  5.469e-02 second:  7.464e-02 infty:  3.312e-01
+Divergence time: 0.424763 first:  5.467e-02 second:  7.462e-02 infty:  3.308e-01
+Divergence time: 0.427876 first:  5.464e-02 second:  7.460e-02 infty:  3.324e-01
+Divergence time: 0.43099 first:  5.461e-02 second:  7.458e-02 infty:  3.423e-01
+Divergence time: 0.434103 first:  5.460e-02 second:  7.457e-02 infty:  3.615e-01
+Divergence time: 0.437216 first:  5.459e-02 second:  7.456e-02 infty:  3.505e-01
+Divergence time: 0.440329 first:  5.457e-02 second:  7.453e-02 infty:  3.354e-01
+Divergence time: 0.443442 first:  5.453e-02 second:  7.450e-02 infty:  3.378e-01
+Divergence time: 0.446555 first:  5.452e-02 second:  7.449e-02 infty:  3.390e-01
+Divergence time: 0.449668 first:  5.450e-02 second:  7.447e-02 infty:  3.399e-01
+Divergence time: 0.452781 first:  5.447e-02 second:  7.445e-02 infty:  3.406e-01
+Divergence time: 0.455895 first:  5.445e-02 second:  7.444e-02 infty:  3.412e-01
+Divergence time: 0.459008 first:  5.444e-02 second:  7.442e-02 infty:  3.416e-01
+Divergence time: 0.462114 first:  5.433e-02 second:  7.429e-02 infty:  3.413e-01
+Divergence time: 0.465221 first:  5.431e-02 second:  7.427e-02 infty:  3.417e-01
+Divergence time: 0.468328 first:  5.430e-02 second:  7.426e-02 infty:  3.413e-01
+Divergence time: 0.471435 first:  5.429e-02 second:  7.425e-02 infty:  3.407e-01
+Divergence time: 0.474542 first:  5.428e-02 second:  7.424e-02 infty:  3.403e-01
+Divergence time: 0.477649 first:  5.426e-02 second:  7.422e-02 infty:  3.416e-01
+Divergence time: 0.480756 first:  5.425e-02 second:  7.421e-02 infty:  3.430e-01
+Divergence time: 0.483862 first:  5.424e-02 second:  7.420e-02 infty:  3.441e-01
+Divergence time: 0.486969 first:  5.424e-02 second:  7.420e-02 infty:  3.451e-01
+Divergence time: 0.490076 first:  5.422e-02 second:  7.418e-02 infty:  3.459e-01
+Divergence time: 0.493183 first:  5.421e-02 second:  7.418e-02 infty:  3.465e-01
+Divergence time: 0.49629 first:  5.421e-02 second:  7.416e-02 infty:  3.470e-01
+Divergence time: 0.499397 first:  5.421e-02 second:  7.415e-02 infty:  3.474e-01
+Divergence time: 0.502503 first:  5.421e-02 second:  7.414e-02 infty:  3.477e-01
+Divergence time: 0.505604 first:  5.412e-02 second:  7.402e-02 infty:  3.474e-01
+Divergence time: 0.508704 first:  5.410e-02 second:  7.399e-02 infty:  3.475e-01
+Divergence time: 0.511805 first:  5.409e-02 second:  7.398e-02 infty:  3.476e-01
+Divergence time: 0.514905 first:  5.407e-02 second:  7.395e-02 infty:  3.480e-01
+Divergence time: 0.518005 first:  5.407e-02 second:  7.394e-02 infty:  3.485e-01
+Divergence time: 0.521106 first:  5.408e-02 second:  7.393e-02 infty:  3.489e-01
+Divergence time: 0.524206 first:  5.406e-02 second:  7.391e-02 infty:  3.495e-01
+Divergence time: 0.527307 first:  5.408e-02 second:  7.391e-02 infty:  3.492e-01
+Divergence time: 0.530407 first:  5.408e-02 second:  7.390e-02 infty:  3.488e-01
+Divergence time: 0.533507 first:  5.408e-02 second:  7.388e-02 infty:  3.486e-01
+Divergence time: 0.536608 first:  5.407e-02 second:  7.387e-02 infty:  3.490e-01
+Divergence time: 0.539708 first:  5.407e-02 second:  7.386e-02 infty:  3.499e-01
+Divergence time: 0.542809 first:  5.408e-02 second:  7.385e-02 infty:  3.507e-01
+Divergence time: 0.545909 first:  5.408e-02 second:  7.385e-02 infty:  3.512e-01
+Divergence time: 0.54901 first:  5.408e-02 second:  7.383e-02 infty:  3.520e-01
+Divergence time: 0.55211 first:  5.408e-02 second:  7.382e-02 infty:  3.518e-01
+Divergence time: 0.55521 first:  5.408e-02 second:  7.381e-02 infty:  3.515e-01
+Divergence time: 0.558304 first:  5.399e-02 second:  7.368e-02 infty:  3.512e-01
+Divergence time: 0.561398 first:  5.398e-02 second:  7.365e-02 infty:  3.510e-01
+Divergence time: 0.564492 first:  5.398e-02 second:  7.364e-02 infty:  3.491e-01
+Divergence time: 0.567585 first:  5.397e-02 second:  7.362e-02 infty:  3.493e-01
+Divergence time: 0.570679 first:  5.396e-02 second:  7.361e-02 infty:  3.496e-01
+Divergence time: 0.573773 first:  5.395e-02 second:  7.360e-02 infty:  3.500e-01
+Divergence time: 0.576867 first:  5.395e-02 second:  7.360e-02 infty:  3.505e-01
+Divergence time: 0.57996 first:  5.395e-02 second:  7.359e-02 infty:  3.509e-01
+Divergence time: 0.583054 first:  5.396e-02 second:  7.359e-02 infty:  3.514e-01
+Divergence time: 0.586148 first:  5.397e-02 second:  7.358e-02 infty:  3.520e-01
+Divergence time: 0.589242 first:  5.397e-02 second:  7.358e-02 infty:  3.526e-01
+Divergence time: 0.592336 first:  5.398e-02 second:  7.357e-02 infty:  3.532e-01
+Divergence time: 0.595429 first:  5.399e-02 second:  7.357e-02 infty:  3.538e-01
+Divergence time: 0.598523 first:  5.400e-02 second:  7.357e-02 infty:  3.545e-01
+Divergence time: 0.601617 first:  5.402e-02 second:  7.357e-02 infty:  3.552e-01
+Divergence time: 0.604711 first:  5.404e-02 second:  7.357e-02 infty:  3.561e-01
+Divergence time: 0.607804 first:  5.406e-02 second:  7.357e-02 infty:  3.570e-01
+Divergence time: 0.610891 first:  5.397e-02 second:  7.343e-02 infty:  3.578e-01
+Divergence time: 0.613978 first:  5.398e-02 second:  7.343e-02 infty:  3.586e-01
+Divergence time: 0.617065 first:  5.399e-02 second:  7.343e-02 infty:  3.595e-01
+Divergence time: 0.620152 first:  5.401e-02 second:  7.342e-02 infty:  3.603e-01
+Divergence time: 0.623239 first:  5.400e-02 second:  7.340e-02 infty:  3.611e-01
+Divergence time: 0.626326 first:  5.398e-02 second:  7.338e-02 infty:  3.619e-01
+Divergence time: 0.629413 first:  5.396e-02 second:  7.336e-02 infty:  3.626e-01
+Divergence time: 0.632493 first:  5.385e-02 second:  7.320e-02 infty:  3.631e-01
+Divergence time: 0.635573 first:  5.382e-02 second:  7.316e-02 infty:  3.637e-01
+Divergence time: 0.638653 first:  5.381e-02 second:  7.315e-02 infty:  3.643e-01
+Divergence time: 0.641733 first:  5.381e-02 second:  7.314e-02 infty:  3.649e-01
+Divergence time: 0.644813 first:  5.381e-02 second:  7.312e-02 infty:  3.655e-01
+Divergence time: 0.647886 first:  5.369e-02 second:  7.298e-02 infty:  3.659e-01
+Divergence time: 0.650959 first:  5.368e-02 second:  7.296e-02 infty:  3.665e-01
+Divergence time: 0.654032 first:  5.368e-02 second:  7.295e-02 infty:  3.671e-01
+Divergence time: 0.657105 first:  5.368e-02 second:  7.293e-02 infty:  3.677e-01
+Divergence time: 0.660178 first:  5.365e-02 second:  7.292e-02 infty:  3.683e-01
+Divergence time: 0.663251 first:  5.366e-02 second:  7.292e-02 infty:  3.689e-01
+Divergence time: 0.666316 first:  5.355e-02 second:  7.279e-02 infty:  3.692e-01
+Divergence time: 0.669382 first:  5.356e-02 second:  7.278e-02 infty:  3.698e-01
+Divergence time: 0.672448 first:  5.358e-02 second:  7.277e-02 infty:  3.703e-01
+Divergence time: 0.675514 first:  5.359e-02 second:  7.277e-02 infty:  3.710e-01
+Divergence time: 0.678573 first:  5.349e-02 second:  7.264e-02 infty:  3.713e-01
+Divergence time: 0.681632 first:  5.349e-02 second:  7.262e-02 infty:  3.714e-01
+Divergence time: 0.684691 first:  5.351e-02 second:  7.262e-02 infty:  3.716e-01
+Divergence time: 0.68775 first:  5.351e-02 second:  7.261e-02 infty:  3.719e-01
+Divergence time: 0.690809 first:  5.352e-02 second:  7.259e-02 infty:  3.722e-01
+Divergence time: 0.69386 first:  5.342e-02 second:  7.245e-02 infty:  3.722e-01
+Divergence time: 0.696912 first:  5.342e-02 second:  7.244e-02 infty:  3.723e-01
+Divergence time: 0.699964 first:  5.342e-02 second:  7.243e-02 infty:  3.723e-01
+Divergence time: 0.703015 first:  5.341e-02 second:  7.240e-02 infty:  3.722e-01
+Divergence time: 0.706067 first:  5.341e-02 second:  7.238e-02 infty:  3.720e-01
+Divergence time: 0.709112 first:  5.328e-02 second:  7.222e-02 infty:  3.717e-01
+Divergence time: 0.712156 first:  5.327e-02 second:  7.220e-02 infty:  3.715e-01
+Divergence time: 0.715201 first:  5.328e-02 second:  7.219e-02 infty:  3.713e-01
+Divergence time: 0.718245 first:  5.328e-02 second:  7.218e-02 infty:  3.711e-01
+Divergence time: 0.721283 first:  5.318e-02 second:  7.205e-02 infty:  3.707e-01
+Divergence time: 0.72432 first:  5.318e-02 second:  7.202e-02 infty:  3.705e-01
+Divergence time: 0.727357 first:  5.318e-02 second:  7.200e-02 infty:  3.703e-01
+Divergence time: 0.730395 first:  5.320e-02 second:  7.200e-02 infty:  3.701e-01
+Divergence time: 0.733425 first:  5.309e-02 second:  7.185e-02 infty:  3.696e-01
+Divergence time: 0.736455 first:  5.309e-02 second:  7.183e-02 infty:  3.693e-01
+Divergence time: 0.739485 first:  5.309e-02 second:  7.182e-02 infty:  3.690e-01
+Divergence time: 0.742515 first:  5.308e-02 second:  7.180e-02 infty:  3.686e-01
+Divergence time: 0.745538 first:  5.297e-02 second:  7.166e-02 infty:  3.680e-01
+Divergence time: 0.748561 first:  5.296e-02 second:  7.163e-02 infty:  3.675e-01
+Divergence time: 0.751583 first:  5.297e-02 second:  7.163e-02 infty:  3.670e-01
+Divergence time: 0.754606 first:  5.298e-02 second:  7.162e-02 infty:  3.662e-01
+Divergence time: 0.757629 first:  5.297e-02 second:  7.161e-02 infty:  3.640e-01
+Divergence time: 0.760645 first:  5.286e-02 second:  7.145e-02 infty:  3.620e-01
+Divergence time: 0.76366 first:  5.287e-02 second:  7.142e-02 infty:  3.605e-01
+Divergence time: 0.766675 first:  5.288e-02 second:  7.142e-02 infty:  3.591e-01
+Divergence time: 0.769691 first:  5.288e-02 second:  7.141e-02 infty:  3.578e-01
+Divergence time: 0.772699 first:  5.277e-02 second:  7.125e-02 infty:  3.564e-01
+Divergence time: 0.775707 first:  5.273e-02 second:  7.122e-02 infty:  3.553e-01
+Divergence time: 0.778715 first:  5.273e-02 second:  7.122e-02 infty:  3.542e-01
+Divergence time: 0.781723 first:  5.274e-02 second:  7.121e-02 infty:  3.538e-01
+Divergence time: 0.784724 first:  5.264e-02 second:  7.107e-02 infty:  3.540e-01
+Divergence time: 0.787725 first:  5.264e-02 second:  7.106e-02 infty:  3.552e-01
+Divergence time: 0.790725 first:  5.263e-02 second:  7.103e-02 infty:  3.556e-01
+Divergence time: 0.793726 first:  5.263e-02 second:  7.101e-02 infty:  3.556e-01
+Divergence time: 0.796719 first:  5.252e-02 second:  7.087e-02 infty:  3.555e-01
+Divergence time: 0.799712 first:  5.251e-02 second:  7.084e-02 infty:  3.541e-01
+Divergence time: 0.802706 first:  5.249e-02 second:  7.082e-02 infty:  3.528e-01
+Divergence time: 0.805699 first:  5.248e-02 second:  7.080e-02 infty:  3.516e-01
+Divergence time: 0.808692 first:  5.246e-02 second:  7.078e-02 infty:  3.492e-01
+Divergence time: 0.811678 first:  5.233e-02 second:  7.063e-02 infty:  3.493e-01
+Divergence time: 0.814664 first:  5.231e-02 second:  7.061e-02 infty:  3.495e-01
+Divergence time: 0.817649 first:  5.230e-02 second:  7.059e-02 infty:  3.497e-01
+Divergence time: 0.820635 first:  5.230e-02 second:  7.058e-02 infty:  3.500e-01
+Divergence time: 0.823613 first:  5.218e-02 second:  7.044e-02 infty:  3.501e-01
+Divergence time: 0.826592 first:  5.216e-02 second:  7.041e-02 infty:  3.503e-01
+Divergence time: 0.82957 first:  5.214e-02 second:  7.039e-02 infty:  3.506e-01
+Divergence time: 0.832548 first:  5.212e-02 second:  7.037e-02 infty:  3.508e-01
+Divergence time: 0.835526 first:  5.212e-02 second:  7.037e-02 infty:  3.510e-01
+Divergence time: 0.838497 first:  5.200e-02 second:  7.022e-02 infty:  3.510e-01
+Divergence time: 0.841467 first:  5.199e-02 second:  7.021e-02 infty:  3.512e-01
+Divergence time: 0.844438 first:  5.198e-02 second:  7.020e-02 infty:  3.515e-01
+Divergence time: 0.847408 first:  5.197e-02 second:  7.019e-02 infty:  3.518e-01
+Divergence time: 0.850379 first:  5.196e-02 second:  7.017e-02 infty:  3.520e-01
+Divergence time: 0.853342 first:  5.183e-02 second:  7.002e-02 infty:  3.520e-01
+Divergence time: 0.856305 first:  5.181e-02 second:  6.998e-02 infty:  3.522e-01
+Divergence time: 0.859268 first:  5.180e-02 second:  6.996e-02 infty:  3.528e-01
+Divergence time: 0.862231 first:  5.181e-02 second:  6.996e-02 infty:  3.540e-01
+Divergence time: 0.865194 first:  5.181e-02 second:  6.996e-02 infty:  3.589e-01
+Divergence time: 0.868149 first:  5.168e-02 second:  6.981e-02 infty:  3.712e-01
+Divergence time: 0.871104 first:  5.166e-02 second:  6.979e-02 infty:  3.821e-01
+Divergence time: 0.874059 first:  5.165e-02 second:  6.978e-02 infty:  3.912e-01
+Divergence time: 0.877015 first:  5.160e-02 second:  6.974e-02 infty:  3.988e-01
+Divergence time: 0.87997 first:  5.158e-02 second:  6.974e-02 infty:  4.051e-01
+Divergence time: 0.882925 first:  5.157e-02 second:  6.973e-02 infty:  4.103e-01
+Divergence time: 0.88588 first:  5.156e-02 second:  6.972e-02 infty:  4.143e-01
+Divergence time: 0.888828 first:  5.143e-02 second:  6.958e-02 infty:  4.175e-01
+Divergence time: 0.891775 first:  5.141e-02 second:  6.955e-02 infty:  4.195e-01
+Divergence time: 0.894723 first:  5.139e-02 second:  6.953e-02 infty:  4.208e-01
+Divergence time: 0.89767 first:  5.137e-02 second:  6.951e-02 infty:  4.213e-01
+Divergence time: 0.900617 first:  5.136e-02 second:  6.950e-02 infty:  4.197e-01
+Divergence time: 0.903565 first:  5.134e-02 second:  6.948e-02 infty:  4.174e-01
+Divergence time: 0.906512 first:  5.131e-02 second:  6.946e-02 infty:  4.149e-01
+Divergence time: 0.90946 first:  5.130e-02 second:  6.945e-02 infty:  4.122e-01
+Divergence time: 0.912407 first:  5.127e-02 second:  6.944e-02 infty:  4.088e-01
+Divergence time: 0.915354 first:  5.126e-02 second:  6.941e-02 infty:  4.049e-01
+Divergence time: 0.918302 first:  5.123e-02 second:  6.938e-02 infty:  4.005e-01
+Divergence time: 0.921241 first:  5.108e-02 second:  6.920e-02 infty:  3.956e-01
+Divergence time: 0.924181 first:  5.104e-02 second:  6.915e-02 infty:  3.902e-01
+Divergence time: 0.92712 first:  5.102e-02 second:  6.913e-02 infty:  3.851e-01
+Divergence time: 0.930059 first:  5.101e-02 second:  6.911e-02 infty:  3.798e-01
+Divergence time: 0.932999 first:  5.098e-02 second:  6.909e-02 infty:  3.743e-01
+Divergence time: 0.93593 first:  5.082e-02 second:  6.890e-02 infty:  3.684e-01
+Divergence time: 0.938861 first:  5.078e-02 second:  6.885e-02 infty:  3.688e-01
+Divergence time: 0.941785 first:  5.064e-02 second:  6.867e-02 infty:  3.688e-01
+Divergence time: 0.944708 first:  5.061e-02 second:  6.863e-02 infty:  3.682e-01
+Divergence time: 0.947623 first:  5.044e-02 second:  6.844e-02 infty:  3.673e-01
+Divergence time: 0.950538 first:  5.040e-02 second:  6.838e-02 infty:  3.658e-01
+Divergence time: 0.953445 first:  5.025e-02 second:  6.819e-02 infty:  3.641e-01
+Divergence time: 0.956352 first:  5.020e-02 second:  6.813e-02 infty:  3.620e-01
+Divergence time: 0.959252 first:  5.006e-02 second:  6.795e-02 infty:  3.596e-01
+Divergence time: 0.962151 first:  5.002e-02 second:  6.791e-02 infty:  3.593e-01
+Divergence time: 0.965041 first:  4.988e-02 second:  6.772e-02 infty:  3.599e-01
+Divergence time: 0.967932 first:  4.985e-02 second:  6.767e-02 infty:  3.629e-01
+Divergence time: 0.970823 first:  4.982e-02 second:  6.763e-02 infty:  3.690e-01
+Divergence time: 0.973706 first:  4.966e-02 second:  6.743e-02 infty:  3.700e-01
+Divergence time: 0.976589 first:  4.963e-02 second:  6.737e-02 infty:  3.692e-01
+Divergence time: 0.979464 first:  4.949e-02 second:  6.719e-02 infty:  3.692e-01
+Divergence time: 0.982339 first:  4.944e-02 second:  6.712e-02 infty:  3.713e-01
+Divergence time: 0.985205 first:  4.929e-02 second:  6.694e-02 infty:  3.731e-01
+Divergence time: 0.988072 first:  4.925e-02 second:  6.687e-02 infty:  3.752e-01
+Divergence time: 0.99093 first:  4.909e-02 second:  6.667e-02 infty:  3.771e-01
+Divergence time: 0.993789 first:  4.904e-02 second:  6.661e-02 infty:  3.792e-01
+Divergence time: 0.996639 first:  4.886e-02 second:  6.641e-02 infty:  3.810e-01
+Divergence time: 0.999482 first:  4.869e-02 second:  6.621e-02 infty:  3.827e-01
+Divergence time: 1.00232 first:  4.864e-02 second:  6.613e-02 infty:  3.847e-01
+Divergence time: 1.00516 first:  4.846e-02 second:  6.593e-02 infty:  3.864e-01
+Divergence time: 1.00799 first:  4.840e-02 second:  6.587e-02 infty:  3.882e-01
+Divergence time: 1.01082 first:  4.824e-02 second:  6.568e-02 infty:  3.896e-01
+Divergence time: 1.01364 first:  4.806e-02 second:  6.547e-02 infty:  3.916e-01
+Divergence time: 1.01646 first:  4.800e-02 second:  6.541e-02 infty:  3.940e-01
+Divergence time: 1.01927 first:  4.782e-02 second:  6.521e-02 infty:  3.955e-01
+Divergence time: 1.02207 first:  4.761e-02 second:  6.499e-02 infty:  3.966e-01
+Divergence time: 1.02487 first:  4.754e-02 second:  6.492e-02 infty:  3.984e-01
+Divergence time: 1.02766 first:  4.735e-02 second:  6.472e-02 infty:  4.096e-01
+Divergence time: 1.03046 first:  4.728e-02 second:  6.466e-02 infty:  4.293e-01
+Divergence time: 1.03324 first:  4.710e-02 second:  6.448e-02 infty:  4.403e-01
+Divergence time: 1.03602 first:  4.693e-02 second:  6.429e-02 infty:  4.465e-01
+Divergence time: 1.0388 first:  4.686e-02 second:  6.422e-02 infty:  4.501e-01
+Divergence time: 1.04157 first:  4.670e-02 second:  6.403e-02 infty:  4.524e-01
+Divergence time: 1.04433 first:  4.652e-02 second:  6.383e-02 infty:  4.541e-01
+Divergence time: 1.04709 first:  4.646e-02 second:  6.378e-02 infty:  4.556e-01
+Divergence time: 1.04985 first:  4.630e-02 second:  6.359e-02 infty:  4.569e-01
+Divergence time: 1.0526 first:  4.625e-02 second:  6.354e-02 infty:  4.586e-01
+Divergence time: 1.05535 first:  4.610e-02 second:  6.337e-02 infty:  4.601e-01
+Divergence time: 1.05809 first:  4.592e-02 second:  6.317e-02 infty:  4.614e-01
+Divergence time: 1.06082 first:  4.586e-02 second:  6.312e-02 infty:  4.635e-01
+Divergence time: 1.06355 first:  4.568e-02 second:  6.294e-02 infty:  4.652e-01
+Divergence time: 1.06628 first:  4.560e-02 second:  6.287e-02 infty:  4.671e-01
+Divergence time: 1.06901 first:  4.543e-02 second:  6.268e-02 infty:  4.687e-01
+Divergence time: 1.07172 first:  4.524e-02 second:  6.249e-02 infty:  4.700e-01
+Divergence time: 1.07444 first:  4.516e-02 second:  6.242e-02 infty:  4.722e-01
+Divergence time: 1.07714 first:  4.496e-02 second:  6.224e-02 infty:  4.738e-01
+Divergence time: 1.07984 first:  4.478e-02 second:  6.206e-02 infty:  4.752e-01
+Divergence time: 1.08254 first:  4.470e-02 second:  6.199e-02 infty:  4.768e-01
+Divergence time: 1.08523 first:  4.453e-02 second:  6.181e-02 infty:  4.780e-01
+Divergence time: 1.08791 first:  4.434e-02 second:  6.162e-02 infty:  4.790e-01
+Divergence time: 1.09059 first:  4.426e-02 second:  6.154e-02 infty:  4.804e-01
+Divergence time: 1.09327 first:  4.409e-02 second:  6.136e-02 infty:  4.868e-01
+Divergence time: 1.09594 first:  4.393e-02 second:  6.118e-02 infty:  4.940e-01
+Divergence time: 1.0986 first:  4.385e-02 second:  6.112e-02 infty:  5.006e-01
+Divergence time: 1.10126 first:  4.368e-02 second:  6.096e-02 infty:  5.054e-01
+Divergence time: 1.10392 first:  4.360e-02 second:  6.090e-02 infty:  5.093e-01
+Divergence time: 1.10657 first:  4.342e-02 second:  6.074e-02 infty:  5.116e-01
+Divergence time: 1.10922 first:  4.334e-02 second:  6.069e-02 infty:  5.134e-01
+Divergence time: 1.11187 first:  4.318e-02 second:  6.053e-02 infty:  5.141e-01
+Divergence time: 1.1145 first:  4.301e-02 second:  6.036e-02 infty:  5.141e-01
+Divergence time: 1.11714 first:  4.293e-02 second:  6.030e-02 infty:  5.144e-01
+Divergence time: 1.11976 first:  4.276e-02 second:  6.014e-02 infty:  5.139e-01
+Divergence time: 1.12238 first:  4.258e-02 second:  5.996e-02 infty:  5.132e-01
+Divergence time: 1.125 first:  4.250e-02 second:  5.991e-02 infty:  5.126e-01
+Divergence time: 1.12762 first:  4.234e-02 second:  5.975e-02 infty:  5.114e-01
+Divergence time: 1.13023 first:  4.225e-02 second:  5.970e-02 infty:  5.104e-01
+Divergence time: 1.13283 first:  4.208e-02 second:  5.954e-02 infty:  5.088e-01
+Divergence time: 1.13544 first:  4.200e-02 second:  5.951e-02 infty:  5.072e-01
+Divergence time: 1.13803 first:  4.182e-02 second:  5.937e-02 infty:  5.102e-01
+Divergence time: 1.14063 first:  4.174e-02 second:  5.933e-02 infty:  5.232e-01
+Divergence time: 1.14322 first:  4.156e-02 second:  5.918e-02 infty:  5.324e-01
+Divergence time: 1.14581 first:  4.145e-02 second:  5.913e-02 infty:  5.400e-01
+Divergence time: 1.14839 first:  4.138e-02 second:  5.911e-02 infty:  5.470e-01
+Divergence time: 1.15097 first:  4.121e-02 second:  5.897e-02 infty:  5.534e-01
+Divergence time: 1.15356 first:  4.113e-02 second:  5.893e-02 infty:  5.596e-01
+Divergence time: 1.15613 first:  4.097e-02 second:  5.879e-02 infty:  5.656e-01
+Divergence time: 1.1587 first:  4.089e-02 second:  5.875e-02 infty:  5.717e-01
+Divergence time: 1.16127 first:  4.081e-02 second:  5.873e-02 infty:  5.778e-01
+Divergence time: 1.16384 first:  4.065e-02 second:  5.859e-02 infty:  5.837e-01
+Divergence time: 1.1664 first:  4.057e-02 second:  5.857e-02 infty:  5.894e-01
+Divergence time: 1.16896 first:  4.041e-02 second:  5.844e-02 infty:  5.951e-01
+Divergence time: 1.17152 first:  4.034e-02 second:  5.841e-02 infty:  6.007e-01
+Divergence time: 1.17407 first:  4.018e-02 second:  5.828e-02 infty:  6.069e-01
+Divergence time: 1.17662 first:  4.012e-02 second:  5.825e-02 infty:  6.162e-01
+Divergence time: 1.17916 first:  3.995e-02 second:  5.811e-02 infty:  6.247e-01
+Divergence time: 1.1817 first:  3.988e-02 second:  5.809e-02 infty:  6.322e-01
+Divergence time: 1.18424 first:  3.983e-02 second:  5.808e-02 infty:  6.387e-01
+Divergence time: 1.18678 first:  3.977e-02 second:  5.807e-02 infty:  6.440e-01
+Divergence time: 1.18932 first:  3.972e-02 second:  5.808e-02 infty:  6.483e-01
+Divergence time: 1.19186 first:  3.959e-02 second:  5.798e-02 infty:  6.513e-01
+Divergence time: 1.19439 first:  3.954e-02 second:  5.797e-02 infty:  6.533e-01
+Divergence time: 1.19692 first:  3.952e-02 second:  5.800e-02 infty:  6.546e-01
+Divergence time: 1.19946 first:  3.950e-02 second:  5.803e-02 infty:  6.553e-01
+Divergence time: 1.20199 first:  3.947e-02 second:  5.805e-02 infty:  6.553e-01
+Divergence time: 1.20453 first:  3.953e-02 second:  5.817e-02 infty:  6.547e-01
+Divergence time: 1.20707 first:  3.953e-02 second:  5.820e-02 infty:  6.534e-01
+Divergence time: 1.20961 first:  3.950e-02 second:  5.824e-02 infty:  6.510e-01
+Divergence time: 1.21215 first:  3.940e-02 second:  5.817e-02 infty:  6.475e-01
+Divergence time: 1.21468 first:  3.939e-02 second:  5.819e-02 infty:  6.486e-01
+Divergence time: 1.21721 first:  3.937e-02 second:  5.821e-02 infty:  6.566e-01
+Divergence time: 1.21975 first:  3.935e-02 second:  5.824e-02 infty:  6.640e-01
+Divergence time: 1.22228 first:  3.936e-02 second:  5.829e-02 infty:  6.705e-01
+Divergence time: 1.22481 first:  3.937e-02 second:  5.835e-02 infty:  6.762e-01
+Divergence time: 1.22736 first:  3.947e-02 second:  5.852e-02 infty:  6.953e-01
+Divergence time: 1.2299 first:  3.948e-02 second:  5.860e-02 infty:  7.151e-01
+Divergence time: 1.23245 first:  3.960e-02 second:  5.880e-02 infty:  7.399e-01
+Divergence time: 1.23499 first:  3.956e-02 second:  5.882e-02 infty:  7.647e-01
+Divergence time: 1.23751 first:  3.940e-02 second:  5.871e-02 infty:  7.880e-01
+Divergence time: 1.24003 first:  3.934e-02 second:  5.871e-02 infty:  8.024e-01
+Divergence time: 1.24253 first:  3.920e-02 second:  5.864e-02 infty:  8.215e-01
+Divergence time: 1.24502 first:  3.917e-02 second:  5.865e-02 infty:  8.360e-01
+Divergence time: 1.2475 first:  3.905e-02 second:  5.857e-02 infty:  8.533e-01
+Divergence time: 1.24996 first:  3.894e-02 second:  5.851e-02 infty:  8.695e-01
+Divergence time: 1.25241 first:  3.892e-02 second:  5.853e-02 infty:  8.841e-01
+Divergence time: 1.25484 first:  3.881e-02 second:  5.847e-02 infty:  8.968e-01
+Divergence time: 1.25727 first:  3.879e-02 second:  5.851e-02 infty:  9.107e-01
+Divergence time: 1.25969 first:  3.877e-02 second:  5.856e-02 infty:  9.036e-01
+Divergence time: 1.26209 first:  3.867e-02 second:  5.852e-02 infty:  9.013e-01
+Divergence time: 1.26448 first:  3.859e-02 second:  5.849e-02 infty:  9.008e-01
+Divergence time: 1.26686 first:  3.860e-02 second:  5.857e-02 infty:  9.017e-01
+Divergence time: 1.26923 first:  3.851e-02 second:  5.858e-02 infty:  9.007e-01
+Divergence time: 1.27158 first:  3.851e-02 second:  5.866e-02 infty:  9.139e-01
+Divergence time: 1.27393 first:  3.854e-02 second:  5.879e-02 infty:  9.553e-01
+Divergence time: 1.27627 first:  3.850e-02 second:  5.886e-02 infty:  9.971e-01
+Divergence time: 1.27859 first:  3.853e-02 second:  5.903e-02 infty:  1.039e+00
+Divergence time: 1.28091 first:  3.847e-02 second:  5.911e-02 infty:  1.082e+00
+Divergence time: 1.28321 first:  3.849e-02 second:  5.931e-02 infty:  1.124e+00
+Divergence time: 1.28551 first:  3.852e-02 second:  5.955e-02 infty:  1.166e+00
+Divergence time: 1.28779 first:  3.852e-02 second:  5.975e-02 infty:  1.207e+00
+Divergence time: 1.29007 first:  3.858e-02 second:  6.003e-02 infty:  1.246e+00
+Divergence time: 1.29233 first:  3.863e-02 second:  6.035e-02 infty:  1.281e+00
+Divergence time: 1.29459 first:  3.861e-02 second:  6.058e-02 infty:  1.314e+00
+Divergence time: 1.29684 first:  3.865e-02 second:  6.090e-02 infty:  1.346e+00
+Divergence time: 1.29907 first:  3.873e-02 second:  6.129e-02 infty:  1.380e+00
+Divergence time: 1.3013 first:  3.873e-02 second:  6.160e-02 infty:  1.409e+00
+Divergence time: 1.30352 first:  3.880e-02 second:  6.201e-02 infty:  1.434e+00
+Divergence time: 1.30573 first:  3.886e-02 second:  6.241e-02 infty:  1.455e+00
+Divergence time: 1.30793 first:  3.885e-02 second:  6.274e-02 infty:  1.472e+00
+Divergence time: 1.31012 first:  3.890e-02 second:  6.316e-02 infty:  1.486e+00
+Divergence time: 1.3123 first:  3.894e-02 second:  6.354e-02 infty:  1.494e+00
+Divergence time: 1.31448 first:  3.898e-02 second:  6.392e-02 infty:  1.500e+00
+Divergence time: 1.31664 first:  3.893e-02 second:  6.419e-02 infty:  1.501e+00
+Divergence time: 1.31879 first:  3.897e-02 second:  6.454e-02 infty:  1.518e+00
+Divergence time: 1.32094 first:  3.906e-02 second:  6.486e-02 infty:  1.526e+00
+Divergence time: 1.32308 first:  3.913e-02 second:  6.516e-02 infty:  1.528e+00
+Divergence time: 1.32522 first:  3.915e-02 second:  6.537e-02 infty:  1.525e+00
+Divergence time: 1.32735 first:  3.917e-02 second:  6.554e-02 infty:  1.518e+00
+Divergence time: 1.32947 first:  3.919e-02 second:  6.564e-02 infty:  1.507e+00
+Divergence time: 1.33159 first:  3.920e-02 second:  6.572e-02 infty:  1.493e+00
+Divergence time: 1.33369 first:  3.919e-02 second:  6.579e-02 infty:  1.475e+00
+Divergence time: 1.3358 first:  3.917e-02 second:  6.582e-02 infty:  1.455e+00
+Divergence time: 1.33789 first:  3.911e-02 second:  6.580e-02 infty:  1.432e+00
+Divergence time: 1.33998 first:  3.905e-02 second:  6.571e-02 infty:  1.405e+00
+Divergence time: 1.34206 first:  3.899e-02 second:  6.559e-02 infty:  1.378e+00
+Divergence time: 1.34414 first:  3.893e-02 second:  6.545e-02 infty:  1.349e+00
+Divergence time: 1.34621 first:  3.890e-02 second:  6.529e-02 infty:  1.318e+00
+Divergence time: 1.34828 first:  3.894e-02 second:  6.519e-02 infty:  1.286e+00
+Divergence time: 1.35034 first:  3.890e-02 second:  6.499e-02 infty:  1.252e+00
+Divergence time: 1.3524 first:  3.894e-02 second:  6.487e-02 infty:  1.218e+00
+Divergence time: 1.35445 first:  3.888e-02 second:  6.463e-02 infty:  1.180e+00
+Divergence time: 1.3565 first:  3.892e-02 second:  6.451e-02 infty:  1.142e+00
+Divergence time: 1.35854 first:  3.892e-02 second:  6.437e-02 infty:  1.104e+00
+Divergence time: 1.36058 first:  3.886e-02 second:  6.416e-02 infty:  1.065e+00
+Divergence time: 1.36261 first:  3.880e-02 second:  6.399e-02 infty:  1.028e+00
+Divergence time: 1.36463 first:  3.873e-02 second:  6.388e-02 infty:  9.897e-01
+Divergence time: 1.36665 first:  3.864e-02 second:  6.372e-02 infty:  9.507e-01
+Divergence time: 1.36867 first:  3.865e-02 second:  6.374e-02 infty:  9.002e-01
+Divergence time: 1.37067 first:  3.854e-02 second:  6.362e-02 infty:  8.749e-01
+Divergence time: 1.37267 first:  3.854e-02 second:  6.359e-02 infty:  8.830e-01
+Divergence time: 1.37465 first:  3.846e-02 second:  6.351e-02 infty:  9.294e-01
+Divergence time: 1.37663 first:  3.837e-02 second:  6.340e-02 infty:  1.014e+00
+Divergence time: 1.37859 first:  3.834e-02 second:  6.335e-02 infty:  1.035e+00
+Divergence time: 1.38055 first:  3.832e-02 second:  6.340e-02 infty:  1.074e+00
+Divergence time: 1.3825 first:  3.824e-02 second:  6.340e-02 infty:  1.110e+00
+Divergence time: 1.38444 first:  3.822e-02 second:  6.352e-02 infty:  1.129e+00
+Divergence time: 1.38638 first:  3.817e-02 second:  6.356e-02 infty:  1.137e+00
+Divergence time: 1.3883 first:  3.810e-02 second:  6.366e-02 infty:  1.163e+00
+Divergence time: 1.39022 first:  3.812e-02 second:  6.380e-02 infty:  1.175e+00
+Divergence time: 1.39213 first:  3.815e-02 second:  6.399e-02 infty:  1.150e+00
+Divergence time: 1.39404 first:  3.820e-02 second:  6.421e-02 infty:  1.170e+00
+Divergence time: 1.39594 first:  3.829e-02 second:  6.441e-02 infty:  1.183e+00
+Divergence time: 1.39783 first:  3.838e-02 second:  6.470e-02 infty:  1.211e+00
+Divergence time: 1.39972 first:  3.842e-02 second:  6.499e-02 infty:  1.181e+00
+Divergence time: 1.4016 first:  3.848e-02 second:  6.538e-02 infty:  1.106e+00
+Divergence time: 1.40348 first:  3.857e-02 second:  6.585e-02 infty:  1.125e+00
+Divergence time: 1.40535 first:  3.866e-02 second:  6.642e-02 infty:  1.148e+00
+Divergence time: 1.40721 first:  3.875e-02 second:  6.701e-02 infty:  1.149e+00
+Divergence time: 1.40907 first:  3.889e-02 second:  6.771e-02 infty:  1.194e+00
+Divergence time: 1.41092 first:  3.905e-02 second:  6.844e-02 infty:  1.312e+00
+Divergence time: 1.41277 first:  3.921e-02 second:  6.917e-02 infty:  1.340e+00
+Divergence time: 1.41461 first:  3.940e-02 second:  6.983e-02 infty:  1.284e+00
+Divergence time: 1.41646 first:  3.960e-02 second:  7.052e-02 infty:  1.302e+00
+Divergence time: 1.41831 first:  3.984e-02 second:  7.127e-02 infty:  1.272e+00
+Divergence time: 1.42016 first:  4.013e-02 second:  7.209e-02 infty:  1.273e+00
+Divergence time: 1.42201 first:  4.036e-02 second:  7.277e-02 infty:  1.354e+00
+Divergence time: 1.42387 first:  4.066e-02 second:  7.365e-02 infty:  1.514e+00
+Divergence time: 1.42573 first:  4.098e-02 second:  7.456e-02 infty:  1.545e+00
+Divergence time: 1.42761 first:  4.140e-02 second:  7.565e-02 infty:  1.473e+00
+Divergence time: 1.4295 first:  4.186e-02 second:  7.680e-02 infty:  1.519e+00
+Divergence time: 1.4314 first:  4.235e-02 second:  7.809e-02 infty:  1.565e+00
+Divergence time: 1.43331 first:  4.275e-02 second:  7.933e-02 infty:  1.606e+00
+Divergence time: 1.43522 first:  4.313e-02 second:  8.055e-02 infty:  1.732e+00
+Divergence time: 1.43715 first:  4.357e-02 second:  8.196e-02 infty:  1.970e+00
+Divergence time: 1.43909 first:  4.403e-02 second:  8.331e-02 infty:  2.008e+00
+Divergence time: 1.44104 first:  4.443e-02 second:  8.448e-02 infty:  1.894e+00
+Divergence time: 1.44301 first:  4.502e-02 second:  8.584e-02 infty:  2.001e+00
+Divergence time: 1.44499 first:  4.556e-02 second:  8.701e-02 infty:  2.132e+00
+Divergence time: 1.44699 first:  4.603e-02 second:  8.798e-02 infty:  2.177e+00
+Divergence time: 1.44898 first:  4.631e-02 second:  8.864e-02 infty:  2.119e+00
+Divergence time: 1.45098 first:  4.657e-02 second:  8.902e-02 infty:  2.002e+00
+Divergence time: 1.45298 first:  4.690e-02 second:  8.934e-02 infty:  1.835e+00
+Divergence time: 1.45499 first:  4.713e-02 second:  8.942e-02 infty:  1.800e+00
+Divergence time: 1.457 first:  4.742e-02 second:  8.976e-02 infty:  1.878e+00
+Divergence time: 1.45902 first:  4.773e-02 second:  9.028e-02 infty:  2.077e+00
+Divergence time: 1.46104 first:  4.791e-02 second:  9.078e-02 infty:  2.279e+00
+Divergence time: 1.46305 first:  4.816e-02 second:  9.150e-02 infty:  2.177e+00
+Divergence time: 1.46507 first:  4.836e-02 second:  9.236e-02 infty:  2.011e+00
+Divergence time: 1.4671 first:  4.858e-02 second:  9.322e-02 infty:  2.201e+00
+Divergence time: 1.46913 first:  4.870e-02 second:  9.388e-02 infty:  2.309e+00
+Divergence time: 1.47116 first:  4.889e-02 second:  9.406e-02 infty:  2.295e+00
+Divergence time: 1.47319 first:  4.895e-02 second:  9.350e-02 infty:  2.129e+00
+Divergence time: 1.47524 first:  4.907e-02 second:  9.248e-02 infty:  1.987e+00
+Divergence time: 1.47729 first:  4.921e-02 second:  9.141e-02 infty:  1.663e+00
+Divergence time: 1.47934 first:  4.930e-02 second:  9.051e-02 infty:  1.611e+00
+Divergence time: 1.48139 first:  4.943e-02 second:  9.010e-02 infty:  1.673e+00
+Divergence time: 1.48345 first:  4.947e-02 second:  9.046e-02 infty:  1.759e+00
+Divergence time: 1.48552 first:  4.960e-02 second:  9.115e-02 infty:  2.064e+00
+Divergence time: 1.48758 first:  4.967e-02 second:  9.180e-02 infty:  2.384e+00
+Divergence time: 1.48966 first:  4.984e-02 second:  9.229e-02 infty:  2.519e+00
+Divergence time: 1.49174 first:  5.005e-02 second:  9.225e-02 infty:  2.436e+00
+Divergence time: 1.49382 first:  5.014e-02 second:  9.131e-02 infty:  2.073e+00
+Divergence time: 1.49591 first:  5.014e-02 second:  9.035e-02 infty:  1.518e+00
+Divergence time: 1.498 first:  5.019e-02 second:  8.989e-02 infty:  1.498e+00
+Divergence time: 1.50009 first:  5.022e-02 second:  9.001e-02 infty:  1.562e+00
+Divergence time: 1.50219 first:  5.041e-02 second:  9.086e-02 infty:  1.915e+00
+Divergence time: 1.50429 first:  5.056e-02 second:  9.169e-02 infty:  2.409e+00
+Divergence time: 1.5064 first:  5.077e-02 second:  9.242e-02 infty:  2.678e+00
+Divergence time: 1.50852 first:  5.092e-02 second:  9.244e-02 infty:  2.660e+00
+Divergence time: 1.51064 first:  5.090e-02 second:  9.167e-02 infty:  2.318e+00
+Divergence time: 1.51277 first:  5.098e-02 second:  9.065e-02 infty:  1.693e+00
+Divergence time: 1.51488 first:  5.088e-02 second:  8.974e-02 infty:  1.342e+00
+Divergence time: 1.517 first:  5.088e-02 second:  8.956e-02 infty:  1.374e+00
+Divergence time: 1.51912 first:  5.099e-02 second:  9.013e-02 infty:  1.733e+00
+Divergence time: 1.52124 first:  5.109e-02 second:  9.101e-02 infty:  2.163e+00
+Divergence time: 1.52336 first:  5.116e-02 second:  9.167e-02 infty:  2.346e+00
+Divergence time: 1.52547 first:  5.104e-02 second:  9.152e-02 infty:  2.246e+00
+Divergence time: 1.52758 first:  5.116e-02 second:  9.102e-02 infty:  1.897e+00
+Divergence time: 1.52968 first:  5.127e-02 second:  9.034e-02 infty:  1.398e+00
+Divergence time: 1.53179 first:  5.136e-02 second:  8.990e-02 infty:  1.310e+00
+Divergence time: 1.5339 first:  5.152e-02 second:  9.009e-02 infty:  1.272e+00
+Divergence time: 1.53601 first:  5.167e-02 second:  9.073e-02 infty:  1.360e+00
+Divergence time: 1.53812 first:  5.188e-02 second:  9.179e-02 infty:  1.710e+00
+Divergence time: 1.54023 first:  5.197e-02 second:  9.244e-02 infty:  1.875e+00
+Divergence time: 1.54234 first:  5.202e-02 second:  9.264e-02 infty:  1.863e+00
+Divergence time: 1.54445 first:  5.205e-02 second:  9.242e-02 infty:  1.661e+00
+Divergence time: 1.54656 first:  5.214e-02 second:  9.192e-02 infty:  1.335e+00
+Divergence time: 1.54866 first:  5.207e-02 second:  9.109e-02 infty:  1.327e+00
+Divergence time: 1.55076 first:  5.210e-02 second:  9.065e-02 infty:  1.399e+00
+Divergence time: 1.55286 first:  5.217e-02 second:  9.067e-02 infty:  1.485e+00
+Divergence time: 1.55497 first:  5.229e-02 second:  9.090e-02 infty:  1.520e+00
+Divergence time: 1.55708 first:  5.238e-02 second:  9.119e-02 infty:  1.526e+00
+Divergence time: 1.55919 first:  5.247e-02 second:  9.170e-02 infty:  1.497e+00
+Divergence time: 1.5613 first:  5.257e-02 second:  9.208e-02 infty:  1.494e+00
+Divergence time: 1.56341 first:  5.259e-02 second:  9.214e-02 infty:  1.543e+00
+Divergence time: 1.56552 first:  5.256e-02 second:  9.196e-02 infty:  1.565e+00
+Divergence time: 1.56763 first:  5.253e-02 second:  9.174e-02 infty:  1.555e+00
+Divergence time: 1.56974 first:  5.250e-02 second:  9.140e-02 infty:  1.514e+00
+Divergence time: 1.57185 first:  5.243e-02 second:  9.108e-02 infty:  1.443e+00
+Divergence time: 1.57396 first:  5.240e-02 second:  9.086e-02 infty:  1.449e+00
+Divergence time: 1.57607 first:  5.238e-02 second:  9.058e-02 infty:  1.442e+00
+Divergence time: 1.57817 first:  5.240e-02 second:  9.035e-02 infty:  1.392e+00
+Divergence time: 1.58028 first:  5.239e-02 second:  9.022e-02 infty:  1.311e+00
+Divergence time: 1.58239 first:  5.232e-02 second:  9.003e-02 infty:  1.322e+00
+Divergence time: 1.5845 first:  5.227e-02 second:  8.985e-02 infty:  1.344e+00
+Divergence time: 1.58661 first:  5.224e-02 second:  8.964e-02 infty:  1.326e+00
+Divergence time: 1.58872 first:  5.220e-02 second:  8.937e-02 infty:  1.272e+00
+Divergence time: 1.59083 first:  5.210e-02 second:  8.905e-02 infty:  1.315e+00
+Divergence time: 1.59294 first:  5.201e-02 second:  8.879e-02 infty:  1.339e+00
+Divergence time: 1.59506 first:  5.206e-02 second:  8.877e-02 infty:  1.325e+00
+Divergence time: 1.59717 first:  5.182e-02 second:  8.849e-02 infty:  1.278e+00
+Divergence time: 1.59928 first:  5.168e-02 second:  8.831e-02 infty:  1.321e+00
+Divergence time: 1.6014 first:  5.173e-02 second:  8.840e-02 infty:  1.366e+00
+Divergence time: 1.60352 first:  5.168e-02 second:  8.834e-02 infty:  1.430e+00
+Divergence time: 1.60564 first:  5.165e-02 second:  8.828e-02 infty:  1.475e+00
+Divergence time: 1.60776 first:  5.160e-02 second:  8.820e-02 infty:  1.499e+00
+Divergence time: 1.60988 first:  5.155e-02 second:  8.817e-02 infty:  1.504e+00
+Divergence time: 1.612 first:  5.150e-02 second:  8.814e-02 infty:  1.490e+00
+Divergence time: 1.61412 first:  5.142e-02 second:  8.794e-02 infty:  1.457e+00
+Divergence time: 1.61624 first:  5.135e-02 second:  8.774e-02 infty:  1.445e+00
+Divergence time: 1.61836 first:  5.128e-02 second:  8.749e-02 infty:  1.423e+00
+Divergence time: 1.62048 first:  5.121e-02 second:  8.726e-02 infty:  1.381e+00
+Divergence time: 1.62261 first:  5.127e-02 second:  8.716e-02 infty:  1.320e+00
+Divergence time: 1.62474 first:  5.120e-02 second:  8.683e-02 infty:  1.242e+00
+Divergence time: 1.62688 first:  5.107e-02 second:  8.640e-02 infty:  1.148e+00
+Divergence time: 1.62901 first:  5.092e-02 second:  8.588e-02 infty:  1.043e+00
+Divergence time: 1.63114 first:  5.079e-02 second:  8.545e-02 infty:  1.025e+00
+Divergence time: 1.63327 first:  5.069e-02 second:  8.496e-02 infty:  1.021e+00
+Divergence time: 1.6354 first:  5.062e-02 second:  8.450e-02 infty:  9.749e-01
+Divergence time: 1.63754 first:  5.052e-02 second:  8.408e-02 infty:  9.691e-01
+Divergence time: 1.63967 first:  5.036e-02 second:  8.367e-02 infty:  9.663e-01
+Divergence time: 1.6418 first:  5.025e-02 second:  8.332e-02 infty:  1.006e+00
+Divergence time: 1.64394 first:  5.029e-02 second:  8.310e-02 infty:  1.016e+00
+Divergence time: 1.64609 first:  5.026e-02 second:  8.281e-02 infty:  9.863e-01
+Divergence time: 1.64823 first:  5.019e-02 second:  8.249e-02 infty:  9.377e-01
+Divergence time: 1.65038 first:  5.009e-02 second:  8.221e-02 infty:  9.509e-01
+Divergence time: 1.65252 first:  4.999e-02 second:  8.194e-02 infty:  9.626e-01
+Divergence time: 1.65468 first:  5.002e-02 second:  8.173e-02 infty:  9.453e-01
+Divergence time: 1.65684 first:  4.985e-02 second:  8.132e-02 infty:  9.270e-01
+Divergence time: 1.659 first:  4.971e-02 second:  8.086e-02 infty:  9.066e-01
+Divergence time: 1.66116 first:  4.960e-02 second:  8.045e-02 infty:  8.834e-01
+Divergence time: 1.66332 first:  4.947e-02 second:  7.988e-02 infty:  8.577e-01
+Divergence time: 1.66547 first:  4.925e-02 second:  7.915e-02 infty:  8.298e-01
+Divergence time: 1.66763 first:  4.906e-02 second:  7.851e-02 infty:  7.994e-01
+Divergence time: 1.66979 first:  4.890e-02 second:  7.793e-02 infty:  7.676e-01
+Divergence time: 1.67195 first:  4.874e-02 second:  7.750e-02 infty:  7.354e-01
+Divergence time: 1.67411 first:  4.855e-02 second:  7.708e-02 infty:  7.035e-01
+Divergence time: 1.67625 first:  4.822e-02 second:  7.646e-02 infty:  6.874e-01
+Divergence time: 1.67839 first:  4.810e-02 second:  7.598e-02 infty:  6.801e-01
+Divergence time: 1.68054 first:  4.802e-02 second:  7.557e-02 infty:  6.656e-01
+Divergence time: 1.68268 first:  4.793e-02 second:  7.512e-02 infty:  6.446e-01
+Divergence time: 1.68483 first:  4.781e-02 second:  7.471e-02 infty:  6.178e-01
+Divergence time: 1.68696 first:  4.747e-02 second:  7.411e-02 infty:  6.027e-01
+Divergence time: 1.68909 first:  4.724e-02 second:  7.362e-02 infty:  6.145e-01
+Divergence time: 1.69122 first:  4.708e-02 second:  7.318e-02 infty:  6.265e-01
+Divergence time: 1.69335 first:  4.697e-02 second:  7.279e-02 infty:  5.837e-01
+Divergence time: 1.69546 first:  4.664e-02 second:  7.216e-02 infty:  5.572e-01
+Divergence time: 1.69757 first:  4.641e-02 second:  7.173e-02 infty:  5.780e-01
+Divergence time: 1.69969 first:  4.629e-02 second:  7.138e-02 infty:  5.950e-01
+Divergence time: 1.70182 first:  4.637e-02 second:  7.130e-02 infty:  6.062e-01
+Divergence time: 1.70395 first:  4.629e-02 second:  7.112e-02 infty:  6.151e-01
+Divergence time: 1.70608 first:  4.618e-02 second:  7.093e-02 infty:  6.401e-01
+Divergence time: 1.70819 first:  4.589e-02 second:  7.045e-02 infty:  6.812e-01
+Divergence time: 1.71031 first:  4.575e-02 second:  7.028e-02 infty:  7.197e-01
+Divergence time: 1.71242 first:  4.561e-02 second:  7.015e-02 infty:  7.554e-01
+Divergence time: 1.71454 first:  4.549e-02 second:  7.011e-02 infty:  7.875e-01
+Divergence time: 1.71667 first:  4.557e-02 second:  7.032e-02 infty:  8.155e-01
+Divergence time: 1.7188 first:  4.552e-02 second:  7.034e-02 infty:  8.386e-01
+Divergence time: 1.72093 first:  4.548e-02 second:  7.031e-02 infty:  8.559e-01
+Divergence time: 1.72306 first:  4.541e-02 second:  7.031e-02 infty:  8.664e-01
+Divergence time: 1.72519 first:  4.536e-02 second:  7.032e-02 infty:  8.693e-01
+Divergence time: 1.72734 first:  4.546e-02 second:  7.042e-02 infty:  8.637e-01
+Divergence time: 1.72948 first:  4.539e-02 second:  7.040e-02 infty:  8.488e-01
+Divergence time: 1.73165 first:  4.553e-02 second:  7.064e-02 infty:  8.236e-01
+Divergence time: 1.73381 first:  4.553e-02 second:  7.066e-02 infty:  7.876e-01
+Divergence time: 1.73598 first:  4.552e-02 second:  7.067e-02 infty:  7.406e-01
+Divergence time: 1.73814 first:  4.542e-02 second:  7.050e-02 infty:  6.826e-01
+Divergence time: 1.74032 first:  4.551e-02 second:  7.069e-02 infty:  6.962e-01
+Divergence time: 1.7425 first:  4.543e-02 second:  7.076e-02 infty:  7.360e-01
+Divergence time: 1.7447 first:  4.558e-02 second:  7.109e-02 infty:  7.736e-01
+Divergence time: 1.74691 first:  4.562e-02 second:  7.131e-02 infty:  8.015e-01
+Divergence time: 1.74913 first:  4.583e-02 second:  7.169e-02 infty:  8.234e-01
+Divergence time: 1.75135 first:  4.588e-02 second:  7.194e-02 infty:  8.276e-01
+Divergence time: 1.75357 first:  4.591e-02 second:  7.209e-02 infty:  8.691e-01
+Divergence time: 1.75581 first:  4.610e-02 second:  7.244e-02 infty:  8.792e-01
+Divergence time: 1.75805 first:  4.612e-02 second:  7.265e-02 infty:  8.413e-01
+Divergence time: 1.76029 first:  4.615e-02 second:  7.276e-02 infty:  7.579e-01
+Divergence time: 1.76253 first:  4.615e-02 second:  7.284e-02 infty:  7.738e-01
+Divergence time: 1.76477 first:  4.613e-02 second:  7.286e-02 infty:  8.301e-01
+Divergence time: 1.76701 first:  4.611e-02 second:  7.287e-02 infty:  8.377e-01
+Divergence time: 1.76925 first:  4.604e-02 second:  7.285e-02 infty:  7.970e-01
+Divergence time: 1.77147 first:  4.578e-02 second:  7.248e-02 infty:  7.944e-01
+Divergence time: 1.77369 first:  4.576e-02 second:  7.240e-02 infty:  8.159e-01
+Divergence time: 1.7759 first:  4.573e-02 second:  7.229e-02 infty:  8.275e-01
+Divergence time: 1.77812 first:  4.573e-02 second:  7.228e-02 infty:  8.247e-01
+Divergence time: 1.78032 first:  4.553e-02 second:  7.205e-02 infty:  8.021e-01
+Divergence time: 1.78252 first:  4.546e-02 second:  7.203e-02 infty:  8.012e-01
+Divergence time: 1.78471 first:  4.541e-02 second:  7.210e-02 infty:  8.585e-01
+Divergence time: 1.78689 first:  4.519e-02 second:  7.190e-02 infty:  9.025e-01
+Divergence time: 1.78906 first:  4.515e-02 second:  7.200e-02 infty:  9.444e-01
+Divergence time: 1.79124 first:  4.518e-02 second:  7.220e-02 infty:  9.697e-01
+Divergence time: 1.79341 first:  4.525e-02 second:  7.239e-02 infty:  9.910e-01
+Divergence time: 1.79559 first:  4.535e-02 second:  7.264e-02 infty:  1.000e+00
+Divergence time: 1.79776 first:  4.545e-02 second:  7.296e-02 infty:  9.956e-01
+Divergence time: 1.79991 first:  4.530e-02 second:  7.291e-02 infty:  9.725e-01
+Divergence time: 1.80206 first:  4.533e-02 second:  7.316e-02 infty:  9.429e-01
+Divergence time: 1.80422 first:  4.539e-02 second:  7.330e-02 infty:  9.275e-01
+Divergence time: 1.80637 first:  4.544e-02 second:  7.354e-02 infty:  8.995e-01
+Divergence time: 1.80852 first:  4.551e-02 second:  7.376e-02 infty:  8.682e-01
+Divergence time: 1.81067 first:  4.562e-02 second:  7.400e-02 infty:  8.826e-01
+Divergence time: 1.81282 first:  4.574e-02 second:  7.417e-02 infty:  9.515e-01
+Divergence time: 1.81497 first:  4.588e-02 second:  7.433e-02 infty:  1.035e+00
+Divergence time: 1.81712 first:  4.594e-02 second:  7.451e-02 infty:  1.105e+00
+Divergence time: 1.81928 first:  4.598e-02 second:  7.469e-02 infty:  1.163e+00
+Divergence time: 1.82143 first:  4.603e-02 second:  7.483e-02 infty:  1.206e+00
+Divergence time: 1.82358 first:  4.613e-02 second:  7.484e-02 infty:  1.227e+00
+Divergence time: 1.82573 first:  4.623e-02 second:  7.486e-02 infty:  1.229e+00
+Divergence time: 1.82788 first:  4.629e-02 second:  7.494e-02 infty:  1.270e+00
+Divergence time: 1.83003 first:  4.635e-02 second:  7.509e-02 infty:  1.312e+00
+Divergence time: 1.83218 first:  4.637e-02 second:  7.524e-02 infty:  1.337e+00
+Divergence time: 1.83434 first:  4.641e-02 second:  7.529e-02 infty:  1.344e+00
+Divergence time: 1.83652 first:  4.674e-02 second:  7.574e-02 infty:  1.341e+00
+Divergence time: 1.8387 first:  4.692e-02 second:  7.602e-02 infty:  1.306e+00
+Divergence time: 1.84088 first:  4.703e-02 second:  7.627e-02 infty:  1.246e+00
+Divergence time: 1.84306 first:  4.708e-02 second:  7.636e-02 infty:  1.166e+00
+Divergence time: 1.84524 first:  4.704e-02 second:  7.622e-02 infty:  1.130e+00
+Divergence time: 1.84742 first:  4.702e-02 second:  7.604e-02 infty:  1.131e+00
+Divergence time: 1.84959 first:  4.701e-02 second:  7.579e-02 infty:  1.125e+00
+Divergence time: 1.85177 first:  4.693e-02 second:  7.547e-02 infty:  1.113e+00
+Divergence time: 1.85399 first:  4.716e-02 second:  7.557e-02 infty:  1.084e+00
+Divergence time: 1.8562 first:  4.715e-02 second:  7.540e-02 infty:  1.061e+00
+Divergence time: 1.85841 first:  4.711e-02 second:  7.519e-02 infty:  1.036e+00
+Divergence time: 1.86062 first:  4.701e-02 second:  7.495e-02 infty:  1.032e+00
+Divergence time: 1.86284 first:  4.694e-02 second:  7.471e-02 infty:  1.028e+00
+Divergence time: 1.86505 first:  4.687e-02 second:  7.445e-02 infty:  1.020e+00
+Divergence time: 1.8673 first:  4.716e-02 second:  7.475e-02 infty:  1.013e+00
+Divergence time: 1.86955 first:  4.716e-02 second:  7.482e-02 infty:  9.991e-01
+Divergence time: 1.8718 first:  4.711e-02 second:  7.476e-02 infty:  9.811e-01
+Divergence time: 1.87405 first:  4.703e-02 second:  7.464e-02 infty:  9.589e-01
+Divergence time: 1.87629 first:  4.697e-02 second:  7.452e-02 infty:  9.325e-01
+Divergence time: 1.87859 first:  4.734e-02 second:  7.503e-02 infty:  9.082e-01
+Divergence time: 1.88088 first:  4.744e-02 second:  7.513e-02 infty:  8.727e-01
+Divergence time: 1.88317 first:  4.741e-02 second:  7.509e-02 infty:  8.520e-01
+Divergence time: 1.88546 first:  4.739e-02 second:  7.500e-02 infty:  8.551e-01
+Divergence time: 1.88775 first:  4.734e-02 second:  7.490e-02 infty:  8.236e-01
+Divergence time: 1.89004 first:  4.736e-02 second:  7.486e-02 infty:  7.653e-01
+Divergence time: 1.89233 first:  4.733e-02 second:  7.480e-02 infty:  7.460e-01
+Divergence time: 1.89462 first:  4.726e-02 second:  7.482e-02 infty:  7.483e-01
+Divergence time: 1.89691 first:  4.725e-02 second:  7.493e-02 infty:  7.573e-01
+Divergence time: 1.8992 first:  4.720e-02 second:  7.512e-02 infty:  7.613e-01
+Divergence time: 1.90149 first:  4.714e-02 second:  7.536e-02 infty:  8.295e-01
+Divergence time: 1.90373 first:  4.656e-02 second:  7.482e-02 infty:  9.013e-01
+Divergence time: 1.90597 first:  4.643e-02 second:  7.482e-02 infty:  8.630e-01
+Divergence time: 1.90821 first:  4.644e-02 second:  7.499e-02 infty:  9.598e-01
+Divergence time: 1.91045 first:  4.641e-02 second:  7.516e-02 infty:  1.028e+00
+Divergence time: 1.91269 first:  4.641e-02 second:  7.522e-02 infty:  1.050e+00
+Divergence time: 1.91493 first:  4.641e-02 second:  7.522e-02 infty:  1.022e+00
+Divergence time: 1.91717 first:  4.640e-02 second:  7.505e-02 infty:  9.437e-01
+Divergence time: 1.9194 first:  4.634e-02 second:  7.481e-02 infty:  8.122e-01
+Divergence time: 1.92164 first:  4.626e-02 second:  7.452e-02 infty:  6.878e-01
+Divergence time: 1.92388 first:  4.621e-02 second:  7.430e-02 infty:  7.572e-01
+Divergence time: 1.92612 first:  4.614e-02 second:  7.408e-02 infty:  7.925e-01
+Divergence time: 1.92836 first:  4.611e-02 second:  7.403e-02 infty:  7.963e-01
+Divergence time: 1.9306 first:  4.604e-02 second:  7.401e-02 infty:  7.748e-01
+Divergence time: 1.93284 first:  4.595e-02 second:  7.396e-02 infty:  7.443e-01
+Divergence time: 1.93508 first:  4.589e-02 second:  7.399e-02 infty:  7.947e-01
+Divergence time: 1.93731 first:  4.584e-02 second:  7.408e-02 infty:  8.417e-01
+Divergence time: 1.93955 first:  4.575e-02 second:  7.417e-02 infty:  9.509e-01
+Divergence time: 1.94179 first:  4.559e-02 second:  7.410e-02 infty:  1.006e+00
+Divergence time: 1.94403 first:  4.551e-02 second:  7.400e-02 infty:  1.006e+00
+Divergence time: 1.94627 first:  4.548e-02 second:  7.390e-02 infty:  9.506e-01
+Divergence time: 1.94851 first:  4.543e-02 second:  7.367e-02 infty:  8.452e-01
+Divergence time: 1.95085 first:  4.639e-02 second:  7.470e-02 infty:  7.368e-01
+Divergence time: 1.95319 first:  4.668e-02 second:  7.496e-02 infty:  7.263e-01
+Divergence time: 1.95553 first:  4.680e-02 second:  7.507e-02 infty:  8.287e-01
+Divergence time: 1.95787 first:  4.679e-02 second:  7.511e-02 infty:  9.216e-01
+Divergence time: 1.96021 first:  4.673e-02 second:  7.517e-02 infty:  1.004e+00
+Divergence time: 1.96255 first:  4.667e-02 second:  7.524e-02 infty:  1.071e+00
+Divergence time: 1.96489 first:  4.664e-02 second:  7.520e-02 infty:  1.119e+00
+Divergence time: 1.96723 first:  4.662e-02 second:  7.511e-02 infty:  1.145e+00
+Divergence time: 1.96957 first:  4.657e-02 second:  7.494e-02 infty:  1.145e+00
+Divergence time: 1.97191 first:  4.653e-02 second:  7.472e-02 infty:  1.118e+00
+Divergence time: 1.97425 first:  4.640e-02 second:  7.441e-02 infty:  1.063e+00
+Divergence time: 1.97659 first:  4.632e-02 second:  7.409e-02 infty:  9.784e-01
+Divergence time: 1.97894 first:  4.621e-02 second:  7.377e-02 infty:  8.671e-01
+Divergence time: 1.98128 first:  4.606e-02 second:  7.346e-02 infty:  7.326e-01
+Divergence time: 1.98362 first:  4.597e-02 second:  7.324e-02 infty:  6.730e-01
+Divergence time: 1.98596 first:  4.587e-02 second:  7.305e-02 infty:  6.231e-01
+Divergence time: 1.9883 first:  4.577e-02 second:  7.298e-02 infty:  7.341e-01
+Divergence time: 1.99064 first:  4.568e-02 second:  7.293e-02 infty:  8.345e-01
+Divergence time: 1.99251 first:  4.109e-02 second:  6.720e-02 infty:  9.002e-01
+Divergence time: 1.99438 first:  3.975e-02 second:  6.528e-02 infty:  9.531e-01
+Divergence time: 1.99626 first:  3.916e-02 second:  6.430e-02 infty:  9.920e-01
+Divergence time: 1.99813 first:  3.882e-02 second:  6.373e-02 infty:  1.016e+00
+Divergence time: 2 first:  3.860e-02 second:  6.331e-02 infty:  1.024e+00
diff --git a/test/reynolds/box/reynolds.ref b/test/reynolds/box/reynolds.ref
new file mode 100644
index 0000000..c8b9e81
--- /dev/null
+++ b/test/reynolds/box/reynolds.ref
@@ -0,0 +1,3 @@
+5 3287.69
+6 12767.3
+7 67250.4
diff --git a/test/reynolds/div5.ref b/test/reynolds/div5.ref
new file mode 100644
index 0000000..346d624
--- /dev/null
+++ b/test/reynolds/div5.ref
@@ -0,0 +1,81 @@
+Divergence time: 0 first:  1.010e-15 second:  1.281e-15 infty:  3.997e-15
+Divergence time: 0.025 first:  3.063e-02 second:  3.764e-02 infty:  9.014e-02
+Divergence time: 0.05 first:  3.217e-02 second:  3.989e-02 infty:  9.940e-02
+Divergence time: 0.075 first:  3.235e-02 second:  4.053e-02 infty:  1.049e-01
+Divergence time: 0.1 first:  3.254e-02 second:  4.140e-02 infty:  1.084e-01
+Divergence time: 0.125 first:  3.292e-02 second:  4.186e-02 infty:  1.102e-01
+Divergence time: 0.15 first:  3.276e-02 second:  4.197e-02 infty:  1.118e-01
+Divergence time: 0.175 first:  3.239e-02 second:  4.182e-02 infty:  1.141e-01
+Divergence time: 0.2 first:  3.289e-02 second:  4.238e-02 infty:  1.140e-01
+Divergence time: 0.225 first:  3.267e-02 second:  4.209e-02 infty:  1.148e-01
+Divergence time: 0.25 first:  3.293e-02 second:  4.238e-02 infty:  1.152e-01
+Divergence time: 0.275 first:  3.297e-02 second:  4.226e-02 infty:  1.156e-01
+Divergence time: 0.3 first:  3.252e-02 second:  4.193e-02 infty:  1.155e-01
+Divergence time: 0.325 first:  3.277e-02 second:  4.203e-02 infty:  1.154e-01
+Divergence time: 0.35 first:  3.299e-02 second:  4.210e-02 infty:  1.153e-01
+Divergence time: 0.375 first:  3.288e-02 second:  4.207e-02 infty:  1.148e-01
+Divergence time: 0.4 first:  3.270e-02 second:  4.206e-02 infty:  1.152e-01
+Divergence time: 0.425 first:  3.266e-02 second:  4.196e-02 infty:  1.158e-01
+Divergence time: 0.45 first:  3.263e-02 second:  4.190e-02 infty:  1.167e-01
+Divergence time: 0.475 first:  3.257e-02 second:  4.179e-02 infty:  1.165e-01
+Divergence time: 0.5 first:  3.257e-02 second:  4.172e-02 infty:  1.164e-01
+Divergence time: 0.525 first:  3.271e-02 second:  4.179e-02 infty:  1.164e-01
+Divergence time: 0.55 first:  3.271e-02 second:  4.180e-02 infty:  1.159e-01
+Divergence time: 0.575 first:  3.276e-02 second:  4.180e-02 infty:  1.148e-01
+Divergence time: 0.6 first:  3.281e-02 second:  4.180e-02 infty:  1.138e-01
+Divergence time: 0.625 first:  3.291e-02 second:  4.185e-02 infty:  1.147e-01
+Divergence time: 0.65 first:  3.290e-02 second:  4.186e-02 infty:  1.152e-01
+Divergence time: 0.675 first:  3.287e-02 second:  4.182e-02 infty:  1.159e-01
+Divergence time: 0.7 first:  3.285e-02 second:  4.178e-02 infty:  1.165e-01
+Divergence time: 0.725 first:  3.282e-02 second:  4.175e-02 infty:  1.169e-01
+Divergence time: 0.75 first:  3.280e-02 second:  4.172e-02 infty:  1.171e-01
+Divergence time: 0.775 first:  3.279e-02 second:  4.170e-02 infty:  1.172e-01
+Divergence time: 0.8 first:  3.285e-02 second:  4.172e-02 infty:  1.174e-01
+Divergence time: 0.825 first:  3.298e-02 second:  4.181e-02 infty:  1.175e-01
+Divergence time: 0.85 first:  3.308e-02 second:  4.189e-02 infty:  1.176e-01
+Divergence time: 0.875 first:  3.309e-02 second:  4.188e-02 infty:  1.175e-01
+Divergence time: 0.9 first:  3.315e-02 second:  4.189e-02 infty:  1.174e-01
+Divergence time: 0.925 first:  3.321e-02 second:  4.192e-02 infty:  1.173e-01
+Divergence time: 0.95 first:  3.321e-02 second:  4.191e-02 infty:  1.172e-01
+Divergence time: 0.975 first:  3.328e-02 second:  4.192e-02 infty:  1.170e-01
+Divergence time: 1 first:  3.338e-02 second:  4.201e-02 infty:  1.168e-01
+Divergence time: 1.025 first:  3.342e-02 second:  4.206e-02 infty:  1.169e-01
+Divergence time: 1.05 first:  3.349e-02 second:  4.214e-02 infty:  1.168e-01
+Divergence time: 1.075 first:  3.348e-02 second:  4.211e-02 infty:  1.168e-01
+Divergence time: 1.1 first:  3.346e-02 second:  4.204e-02 infty:  1.167e-01
+Divergence time: 1.125 first:  3.345e-02 second:  4.197e-02 infty:  1.167e-01
+Divergence time: 1.15 first:  3.349e-02 second:  4.197e-02 infty:  1.166e-01
+Divergence time: 1.175 first:  3.349e-02 second:  4.198e-02 infty:  1.167e-01
+Divergence time: 1.2 first:  3.356e-02 second:  4.204e-02 infty:  1.167e-01
+Divergence time: 1.225 first:  3.363e-02 second:  4.210e-02 infty:  1.168e-01
+Divergence time: 1.25 first:  3.366e-02 second:  4.209e-02 infty:  1.169e-01
+Divergence time: 1.275 first:  3.369e-02 second:  4.201e-02 infty:  1.171e-01
+Divergence time: 1.3 first:  3.370e-02 second:  4.192e-02 infty:  1.173e-01
+Divergence time: 1.325 first:  3.366e-02 second:  4.184e-02 infty:  1.174e-01
+Divergence time: 1.35 first:  3.361e-02 second:  4.180e-02 infty:  1.175e-01
+Divergence time: 1.375 first:  3.357e-02 second:  4.179e-02 infty:  1.176e-01
+Divergence time: 1.4 first:  3.354e-02 second:  4.175e-02 infty:  1.177e-01
+Divergence time: 1.425 first:  3.350e-02 second:  4.173e-02 infty:  1.179e-01
+Divergence time: 1.45 first:  3.340e-02 second:  4.161e-02 infty:  1.180e-01
+Divergence time: 1.475 first:  3.337e-02 second:  4.156e-02 infty:  1.181e-01
+Divergence time: 1.5 first:  3.334e-02 second:  4.153e-02 infty:  1.181e-01
+Divergence time: 1.525 first:  3.315e-02 second:  4.134e-02 infty:  1.181e-01
+Divergence time: 1.55 first:  3.310e-02 second:  4.134e-02 infty:  1.180e-01
+Divergence time: 1.575 first:  3.308e-02 second:  4.135e-02 infty:  1.180e-01
+Divergence time: 1.6 first:  3.277e-02 second:  4.104e-02 infty:  1.178e-01
+Divergence time: 1.625 first:  3.271e-02 second:  4.105e-02 infty:  1.176e-01
+Divergence time: 1.65 first:  3.265e-02 second:  4.103e-02 infty:  1.175e-01
+Divergence time: 1.675 first:  3.265e-02 second:  4.104e-02 infty:  1.172e-01
+Divergence time: 1.7 first:  3.249e-02 second:  4.092e-02 infty:  1.170e-01
+Divergence time: 1.725 first:  3.242e-02 second:  4.089e-02 infty:  1.170e-01
+Divergence time: 1.75 first:  3.236e-02 second:  4.085e-02 infty:  1.180e-01
+Divergence time: 1.775 first:  3.228e-02 second:  4.079e-02 infty:  1.185e-01
+Divergence time: 1.8 first:  3.220e-02 second:  4.071e-02 infty:  1.184e-01
+Divergence time: 1.825 first:  3.218e-02 second:  4.071e-02 infty:  1.182e-01
+Divergence time: 1.85 first:  3.211e-02 second:  4.065e-02 infty:  1.180e-01
+Divergence time: 1.875 first:  3.210e-02 second:  4.064e-02 infty:  1.179e-01
+Divergence time: 1.9 first:  3.202e-02 second:  4.063e-02 infty:  1.181e-01
+Divergence time: 1.925 first:  3.200e-02 second:  4.060e-02 infty:  1.179e-01
+Divergence time: 1.95 first:  3.188e-02 second:  4.053e-02 infty:  1.216e-01
+Divergence time: 1.975 first:  3.180e-02 second:  4.049e-02 infty:  1.241e-01
+Divergence time: 2 first:  3.170e-02 second:  4.034e-02 infty:  1.253e-01
diff --git a/test/reynolds/div6.ref b/test/reynolds/div6.ref
new file mode 100644
index 0000000..4f1087a
--- /dev/null
+++ b/test/reynolds/div6.ref
@@ -0,0 +1,161 @@
+Divergence time: 0 first:  1.728e-15 second:  2.338e-15 infty:  8.882e-15
+Divergence time: 0.0125 first:  4.108e-03 second:  5.293e-03 infty:  3.301e-02
+Divergence time: 0.025 first:  4.450e-03 second:  5.800e-03 infty:  3.637e-02
+Divergence time: 0.0375 first:  4.500e-03 second:  5.944e-03 infty:  3.539e-02
+Divergence time: 0.05 first:  4.504e-03 second:  6.112e-03 infty:  4.205e-02
+Divergence time: 0.0625 first:  4.635e-03 second:  6.241e-03 infty:  3.425e-02
+Divergence time: 0.075 first:  4.744e-03 second:  6.439e-03 infty:  3.105e-02
+Divergence time: 0.0875 first:  4.843e-03 second:  6.574e-03 infty:  4.007e-02
+Divergence time: 0.1 first:  4.875e-03 second:  6.714e-03 infty:  4.334e-02
+Divergence time: 0.1125 first:  4.858e-03 second:  6.779e-03 infty:  4.493e-02
+Divergence time: 0.125 first:  4.928e-03 second:  6.853e-03 infty:  3.663e-02
+Divergence time: 0.1375 first:  4.989e-03 second:  6.989e-03 infty:  4.175e-02
+Divergence time: 0.15 first:  4.984e-03 second:  7.061e-03 infty:  4.321e-02
+Divergence time: 0.1625 first:  5.015e-03 second:  7.116e-03 infty:  4.220e-02
+Divergence time: 0.175 first:  5.016e-03 second:  7.044e-03 infty:  4.208e-02
+Divergence time: 0.1875 first:  4.945e-03 second:  6.878e-03 infty:  4.207e-02
+Divergence time: 0.2 first:  5.009e-03 second:  7.019e-03 infty:  4.250e-02
+Divergence time: 0.2125 first:  5.022e-03 second:  7.010e-03 infty:  4.085e-02
+Divergence time: 0.225 first:  4.966e-03 second:  6.907e-03 infty:  4.188e-02
+Divergence time: 0.2375 first:  5.006e-03 second:  7.072e-03 infty:  4.216e-02
+Divergence time: 0.25 first:  4.958e-03 second:  6.939e-03 infty:  4.029e-02
+Divergence time: 0.2625 first:  4.953e-03 second:  6.969e-03 infty:  4.169e-02
+Divergence time: 0.275 first:  4.977e-03 second:  6.992e-03 infty:  3.786e-02
+Divergence time: 0.2875 first:  4.945e-03 second:  6.969e-03 infty:  4.430e-02
+Divergence time: 0.3 first:  4.931e-03 second:  7.007e-03 infty:  4.844e-02
+Divergence time: 0.3125 first:  4.899e-03 second:  6.944e-03 infty:  4.746e-02
+Divergence time: 0.325 first:  4.878e-03 second:  6.983e-03 infty:  5.502e-02
+Divergence time: 0.3375 first:  4.920e-03 second:  7.061e-03 infty:  5.593e-02
+Divergence time: 0.35 first:  4.906e-03 second:  6.936e-03 infty:  4.465e-02
+Divergence time: 0.3625 first:  4.952e-03 second:  6.977e-03 infty:  4.860e-02
+Divergence time: 0.375 first:  4.989e-03 second:  7.015e-03 infty:  4.853e-02
+Divergence time: 0.3875 first:  5.018e-03 second:  6.992e-03 infty:  4.490e-02
+Divergence time: 0.4 first:  5.021e-03 second:  6.962e-03 infty:  3.987e-02
+Divergence time: 0.4125 first:  5.005e-03 second:  6.888e-03 infty:  3.935e-02
+Divergence time: 0.425 first:  4.990e-03 second:  6.783e-03 infty:  3.035e-02
+Divergence time: 0.4375 first:  4.983e-03 second:  6.806e-03 infty:  3.246e-02
+Divergence time: 0.45 first:  4.952e-03 second:  6.769e-03 infty:  3.614e-02
+Divergence time: 0.4625 first:  4.923e-03 second:  6.782e-03 infty:  3.773e-02
+Divergence time: 0.475 first:  4.881e-03 second:  6.744e-03 infty:  3.816e-02
+Divergence time: 0.4875 first:  4.849e-03 second:  6.717e-03 infty:  3.818e-02
+Divergence time: 0.5 first:  4.834e-03 second:  6.689e-03 infty:  3.818e-02
+Divergence time: 0.5125 first:  4.828e-03 second:  6.669e-03 infty:  3.812e-02
+Divergence time: 0.525 first:  4.826e-03 second:  6.649e-03 infty:  3.805e-02
+Divergence time: 0.5375 first:  4.825e-03 second:  6.636e-03 infty:  3.800e-02
+Divergence time: 0.55 first:  4.825e-03 second:  6.626e-03 infty:  3.798e-02
+Divergence time: 0.5625 first:  4.824e-03 second:  6.619e-03 infty:  3.796e-02
+Divergence time: 0.575 first:  4.824e-03 second:  6.613e-03 infty:  3.795e-02
+Divergence time: 0.5875 first:  4.825e-03 second:  6.610e-03 infty:  3.794e-02
+Divergence time: 0.6 first:  4.825e-03 second:  6.607e-03 infty:  3.794e-02
+Divergence time: 0.6125 first:  4.825e-03 second:  6.605e-03 infty:  3.793e-02
+Divergence time: 0.625 first:  4.825e-03 second:  6.603e-03 infty:  3.793e-02
+Divergence time: 0.6375 first:  4.825e-03 second:  6.601e-03 infty:  3.792e-02
+Divergence time: 0.65 first:  4.825e-03 second:  6.600e-03 infty:  3.792e-02
+Divergence time: 0.6625 first:  4.825e-03 second:  6.599e-03 infty:  3.791e-02
+Divergence time: 0.675 first:  4.825e-03 second:  6.599e-03 infty:  3.791e-02
+Divergence time: 0.6875 first:  4.825e-03 second:  6.598e-03 infty:  3.791e-02
+Divergence time: 0.7 first:  4.825e-03 second:  6.597e-03 infty:  3.790e-02
+Divergence time: 0.7125 first:  4.825e-03 second:  6.597e-03 infty:  3.790e-02
+Divergence time: 0.725 first:  4.825e-03 second:  6.596e-03 infty:  3.789e-02
+Divergence time: 0.7375 first:  4.825e-03 second:  6.595e-03 infty:  3.789e-02
+Divergence time: 0.75 first:  4.825e-03 second:  6.595e-03 infty:  3.789e-02
+Divergence time: 0.7625 first:  4.826e-03 second:  6.594e-03 infty:  3.791e-02
+Divergence time: 0.775 first:  4.826e-03 second:  6.593e-03 infty:  3.792e-02
+Divergence time: 0.7875 first:  4.827e-03 second:  6.560e-03 infty:  3.794e-02
+Divergence time: 0.8 first:  4.833e-03 second:  6.585e-03 infty:  3.795e-02
+Divergence time: 0.8125 first:  4.835e-03 second:  6.568e-03 infty:  3.796e-02
+Divergence time: 0.825 first:  4.840e-03 second:  6.563e-03 infty:  3.796e-02
+Divergence time: 0.8375 first:  4.848e-03 second:  6.580e-03 infty:  3.810e-02
+Divergence time: 0.85 first:  4.855e-03 second:  6.601e-03 infty:  3.849e-02
+Divergence time: 0.8625 first:  4.858e-03 second:  6.587e-03 infty:  3.848e-02
+Divergence time: 0.875 first:  4.866e-03 second:  6.628e-03 infty:  3.845e-02
+Divergence time: 0.8875 first:  4.870e-03 second:  6.634e-03 infty:  3.842e-02
+Divergence time: 0.9 first:  4.872e-03 second:  6.650e-03 infty:  3.839e-02
+Divergence time: 0.9125 first:  4.873e-03 second:  6.657e-03 infty:  3.839e-02
+Divergence time: 0.925 first:  4.876e-03 second:  6.660e-03 infty:  3.842e-02
+Divergence time: 0.9375 first:  4.875e-03 second:  6.641e-03 infty:  3.839e-02
+Divergence time: 0.95 first:  4.875e-03 second:  6.620e-03 infty:  3.831e-02
+Divergence time: 0.9625 first:  4.881e-03 second:  6.629e-03 infty:  3.827e-02
+Divergence time: 0.975 first:  4.886e-03 second:  6.615e-03 infty:  3.826e-02
+Divergence time: 0.9875 first:  4.894e-03 second:  6.661e-03 infty:  3.828e-02
+Divergence time: 1 first:  4.898e-03 second:  6.642e-03 infty:  3.838e-02
+Divergence time: 1.0125 first:  4.907e-03 second:  6.690e-03 infty:  3.841e-02
+Divergence time: 1.025 first:  4.913e-03 second:  6.698e-03 infty:  3.846e-02
+Divergence time: 1.0375 first:  4.918e-03 second:  6.715e-03 infty:  3.844e-02
+Divergence time: 1.05 first:  4.919e-03 second:  6.704e-03 infty:  3.837e-02
+Divergence time: 1.0625 first:  4.921e-03 second:  6.703e-03 infty:  3.853e-02
+Divergence time: 1.075 first:  4.921e-03 second:  6.664e-03 infty:  3.850e-02
+Divergence time: 1.0875 first:  4.925e-03 second:  6.698e-03 infty:  3.841e-02
+Divergence time: 1.1 first:  4.935e-03 second:  6.705e-03 infty:  3.835e-02
+Divergence time: 1.1125 first:  4.941e-03 second:  6.746e-03 infty:  3.831e-02
+Divergence time: 1.125 first:  4.946e-03 second:  6.747e-03 infty:  3.774e-02
+Divergence time: 1.1375 first:  4.952e-03 second:  6.775e-03 infty:  3.774e-02
+Divergence time: 1.15 first:  4.955e-03 second:  6.744e-03 infty:  3.772e-02
+Divergence time: 1.1625 first:  4.948e-03 second:  6.783e-03 infty:  3.763e-02
+Divergence time: 1.175 first:  4.945e-03 second:  6.731e-03 infty:  3.752e-02
+Divergence time: 1.1875 first:  4.936e-03 second:  6.775e-03 infty:  4.036e-02
+Divergence time: 1.2 first:  4.941e-03 second:  6.795e-03 infty:  4.154e-02
+Divergence time: 1.2125 first:  4.953e-03 second:  6.817e-03 infty:  4.165e-02
+Divergence time: 1.225 first:  4.958e-03 second:  6.812e-03 infty:  4.153e-02
+Divergence time: 1.2375 first:  4.932e-03 second:  6.782e-03 infty:  4.163e-02
+Divergence time: 1.25 first:  4.929e-03 second:  6.821e-03 infty:  4.838e-02
+Divergence time: 1.2625 first:  4.932e-03 second:  6.816e-03 infty:  4.151e-02
+Divergence time: 1.275 first:  4.939e-03 second:  6.854e-03 infty:  4.837e-02
+Divergence time: 1.2875 first:  4.930e-03 second:  6.825e-03 infty:  4.358e-02
+Divergence time: 1.3 first:  4.924e-03 second:  6.863e-03 infty:  4.831e-02
+Divergence time: 1.3125 first:  4.929e-03 second:  6.861e-03 infty:  4.352e-02
+Divergence time: 1.325 first:  4.929e-03 second:  6.857e-03 infty:  4.345e-02
+Divergence time: 1.3375 first:  4.914e-03 second:  6.871e-03 infty:  4.823e-02
+Divergence time: 1.35 first:  4.909e-03 second:  6.843e-03 infty:  4.706e-02
+Divergence time: 1.3625 first:  4.914e-03 second:  6.852e-03 infty:  4.680e-02
+Divergence time: 1.375 first:  4.920e-03 second:  6.849e-03 infty:  4.721e-02
+Divergence time: 1.3875 first:  4.892e-03 second:  6.842e-03 infty:  5.216e-02
+Divergence time: 1.4 first:  4.900e-03 second:  6.857e-03 infty:  5.335e-02
+Divergence time: 1.4125 first:  4.922e-03 second:  6.868e-03 infty:  5.215e-02
+Divergence time: 1.425 first:  4.915e-03 second:  6.843e-03 infty:  5.333e-02
+Divergence time: 1.4375 first:  4.888e-03 second:  6.804e-03 infty:  5.194e-02
+Divergence time: 1.45 first:  4.905e-03 second:  6.812e-03 infty:  5.258e-02
+Divergence time: 1.4625 first:  4.876e-03 second:  6.775e-03 infty:  5.752e-02
+Divergence time: 1.475 first:  4.893e-03 second:  6.796e-03 infty:  5.840e-02
+Divergence time: 1.4875 first:  4.887e-03 second:  6.753e-03 infty:  5.750e-02
+Divergence time: 1.5 first:  4.860e-03 second:  6.683e-03 infty:  4.741e-02
+Divergence time: 1.5125 first:  4.877e-03 second:  6.693e-03 infty:  5.058e-02
+Divergence time: 1.525 first:  4.861e-03 second:  6.621e-03 infty:  4.506e-02
+Divergence time: 1.5375 first:  4.876e-03 second:  6.689e-03 infty:  5.153e-02
+Divergence time: 1.55 first:  4.873e-03 second:  6.652e-03 infty:  5.303e-02
+Divergence time: 1.5625 first:  4.868e-03 second:  6.688e-03 infty:  5.433e-02
+Divergence time: 1.575 first:  4.886e-03 second:  6.643e-03 infty:  4.598e-02
+Divergence time: 1.5875 first:  4.894e-03 second:  6.646e-03 infty:  4.527e-02
+Divergence time: 1.6 first:  4.873e-03 second:  6.607e-03 infty:  4.588e-02
+Divergence time: 1.6125 first:  4.849e-03 second:  6.574e-03 infty:  5.281e-02
+Divergence time: 1.625 first:  4.873e-03 second:  6.646e-03 infty:  5.506e-02
+Divergence time: 1.6375 first:  4.847e-03 second:  6.546e-03 infty:  4.231e-02
+Divergence time: 1.65 first:  4.852e-03 second:  6.601e-03 infty:  4.825e-02
+Divergence time: 1.6625 first:  4.867e-03 second:  6.607e-03 infty:  4.993e-02
+Divergence time: 1.675 first:  4.875e-03 second:  6.619e-03 infty:  4.590e-02
+Divergence time: 1.6875 first:  4.871e-03 second:  6.609e-03 infty:  5.504e-02
+Divergence time: 1.7 first:  4.849e-03 second:  6.556e-03 infty:  4.574e-02
+Divergence time: 1.7125 first:  4.836e-03 second:  6.500e-03 infty:  3.902e-02
+Divergence time: 1.725 first:  4.818e-03 second:  6.486e-03 infty:  4.160e-02
+Divergence time: 1.7375 first:  4.822e-03 second:  6.550e-03 infty:  4.993e-02
+Divergence time: 1.75 first:  4.833e-03 second:  6.549e-03 infty:  4.085e-02
+Divergence time: 1.7625 first:  4.830e-03 second:  6.546e-03 infty:  4.966e-02
+Divergence time: 1.775 first:  4.841e-03 second:  6.611e-03 infty:  4.870e-02
+Divergence time: 1.7875 first:  4.844e-03 second:  6.567e-03 infty:  4.231e-02
+Divergence time: 1.8 first:  4.860e-03 second:  6.647e-03 infty:  4.774e-02
+Divergence time: 1.8125 first:  4.849e-03 second:  6.599e-03 infty:  4.883e-02
+Divergence time: 1.825 first:  4.825e-03 second:  6.537e-03 infty:  4.565e-02
+Divergence time: 1.8375 first:  4.819e-03 second:  6.559e-03 infty:  4.660e-02
+Divergence time: 1.85 first:  4.798e-03 second:  6.481e-03 infty:  4.013e-02
+Divergence time: 1.8625 first:  4.814e-03 second:  6.550e-03 infty:  3.996e-02
+Divergence time: 1.875 first:  4.802e-03 second:  6.512e-03 infty:  4.752e-02
+Divergence time: 1.8875 first:  4.755e-03 second:  6.451e-03 infty:  4.872e-02
+Divergence time: 1.9 first:  4.762e-03 second:  6.484e-03 infty:  4.596e-02
+Divergence time: 1.9125 first:  4.775e-03 second:  6.530e-03 infty:  5.154e-02
+Divergence time: 1.925 first:  4.785e-03 second:  6.541e-03 infty:  5.305e-02
+Divergence time: 1.9375 first:  4.798e-03 second:  6.529e-03 infty:  5.181e-02
+Divergence time: 1.95 first:  4.799e-03 second:  6.519e-03 infty:  4.738e-02
+Divergence time: 1.9625 first:  4.779e-03 second:  6.504e-03 infty:  4.865e-02
+Divergence time: 1.975 first:  4.784e-03 second:  6.500e-03 infty:  5.252e-02
+Divergence time: 1.9875 first:  4.790e-03 second:  6.517e-03 infty:  4.661e-02
+Divergence time: 2 first:  4.796e-03 second:  6.541e-03 infty:  3.884e-02
diff --git a/test/reynolds/div7.ref b/test/reynolds/div7.ref
new file mode 100644
index 0000000..eb1c78f
--- /dev/null
+++ b/test/reynolds/div7.ref
@@ -0,0 +1,321 @@
+Divergence time: 0 first:  3.825e-15 second:  5.208e-15 infty:  2.487e-14
+Divergence time: 0.00625 first:  5.328e-04 second:  8.353e-04 infty:  1.662e-02
+Divergence time: 0.0125 first:  5.912e-04 second:  9.907e-04 infty:  1.738e-02
+Divergence time: 0.01875 first:  6.159e-04 second:  1.043e-03 infty:  1.687e-02
+Divergence time: 0.025 first:  6.530e-04 second:  1.188e-03 infty:  2.282e-02
+Divergence time: 0.03125 first:  6.739e-04 second:  1.171e-03 infty:  2.117e-02
+Divergence time: 0.0375 first:  6.978e-04 second:  1.242e-03 infty:  2.399e-02
+Divergence time: 0.04375 first:  7.196e-04 second:  1.285e-03 infty:  2.014e-02
+Divergence time: 0.05 first:  7.468e-04 second:  1.351e-03 infty:  2.136e-02
+Divergence time: 0.05625 first:  7.624e-04 second:  1.383e-03 infty:  2.404e-02
+Divergence time: 0.0625 first:  7.811e-04 second:  1.416e-03 infty:  2.200e-02
+Divergence time: 0.06875 first:  7.969e-04 second:  1.440e-03 infty:  2.146e-02
+Divergence time: 0.075 first:  8.114e-04 second:  1.471e-03 infty:  2.215e-02
+Divergence time: 0.08125 first:  8.204e-04 second:  1.493e-03 infty:  2.307e-02
+Divergence time: 0.0875 first:  8.328e-04 second:  1.526e-03 infty:  2.322e-02
+Divergence time: 0.09375 first:  8.411e-04 second:  1.537e-03 infty:  2.145e-02
+Divergence time: 0.1 first:  8.404e-04 second:  1.530e-03 infty:  2.222e-02
+Divergence time: 0.10625 first:  8.479e-04 second:  1.555e-03 infty:  2.056e-02
+Divergence time: 0.1125 first:  8.562e-04 second:  1.581e-03 infty:  2.219e-02
+Divergence time: 0.11875 first:  8.614e-04 second:  1.593e-03 infty:  2.148e-02
+Divergence time: 0.125 first:  8.623e-04 second:  1.584e-03 infty:  2.224e-02
+Divergence time: 0.13125 first:  8.620e-04 second:  1.574e-03 infty:  2.160e-02
+Divergence time: 0.1375 first:  8.643e-04 second:  1.581e-03 infty:  2.148e-02
+Divergence time: 0.14375 first:  8.643e-04 second:  1.588e-03 infty:  2.189e-02
+Divergence time: 0.15 first:  8.700e-04 second:  1.597e-03 infty:  2.086e-02
+Divergence time: 0.15625 first:  8.790e-04 second:  1.618e-03 infty:  2.222e-02
+Divergence time: 0.1625 first:  8.833e-04 second:  1.641e-03 infty:  2.242e-02
+Divergence time: 0.16875 first:  8.789e-04 second:  1.634e-03 infty:  2.203e-02
+Divergence time: 0.175 first:  8.761e-04 second:  1.613e-03 infty:  1.963e-02
+Divergence time: 0.18125 first:  8.760e-04 second:  1.614e-03 infty:  2.191e-02
+Divergence time: 0.1875 first:  8.796e-04 second:  1.627e-03 infty:  1.838e-02
+Divergence time: 0.19375 first:  8.846e-04 second:  1.653e-03 infty:  2.139e-02
+Divergence time: 0.2 first:  8.859e-04 second:  1.650e-03 infty:  1.823e-02
+Divergence time: 0.20625 first:  8.836e-04 second:  1.645e-03 infty:  2.136e-02
+Divergence time: 0.2125 first:  8.836e-04 second:  1.640e-03 infty:  1.818e-02
+Divergence time: 0.21875 first:  8.782e-04 second:  1.621e-03 infty:  2.129e-02
+Divergence time: 0.225 first:  8.823e-04 second:  1.648e-03 infty:  1.816e-02
+Divergence time: 0.23125 first:  8.876e-04 second:  1.678e-03 infty:  2.127e-02
+Divergence time: 0.2375 first:  8.900e-04 second:  1.685e-03 infty:  1.813e-02
+Divergence time: 0.24375 first:  8.800e-04 second:  1.638e-03 infty:  2.125e-02
+Divergence time: 0.25 first:  8.758e-04 second:  1.625e-03 infty:  1.808e-02
+Divergence time: 0.25625 first:  8.716e-04 second:  1.620e-03 infty:  2.121e-02
+Divergence time: 0.2625 first:  8.701e-04 second:  1.623e-03 infty:  1.808e-02
+Divergence time: 0.26875 first:  8.674e-04 second:  1.614e-03 infty:  2.122e-02
+Divergence time: 0.275 first:  8.692e-04 second:  1.632e-03 infty:  1.803e-02
+Divergence time: 0.28125 first:  8.664e-04 second:  1.616e-03 infty:  2.155e-02
+Divergence time: 0.2875 first:  8.614e-04 second:  1.598e-03 infty:  1.806e-02
+Divergence time: 0.29375 first:  8.599e-04 second:  1.598e-03 infty:  2.135e-02
+Divergence time: 0.3 first:  8.552e-04 second:  1.584e-03 infty:  2.199e-02
+Divergence time: 0.30625 first:  8.546e-04 second:  1.592e-03 infty:  2.124e-02
+Divergence time: 0.3125 first:  8.545e-04 second:  1.587e-03 infty:  2.075e-02
+Divergence time: 0.31875 first:  8.558e-04 second:  1.597e-03 infty:  2.128e-02
+Divergence time: 0.325 first:  8.520e-04 second:  1.589e-03 infty:  2.262e-02
+Divergence time: 0.33125 first:  8.499e-04 second:  1.594e-03 infty:  2.139e-02
+Divergence time: 0.3375 first:  8.469e-04 second:  1.581e-03 infty:  2.087e-02
+Divergence time: 0.34375 first:  8.407e-04 second:  1.557e-03 infty:  2.127e-02
+Divergence time: 0.35 first:  8.374e-04 second:  1.567e-03 infty:  2.233e-02
+Divergence time: 0.35625 first:  8.346e-04 second:  1.552e-03 infty:  2.438e-02
+Divergence time: 0.3625 first:  8.332e-04 second:  1.546e-03 infty:  2.132e-02
+Divergence time: 0.36875 first:  8.272e-04 second:  1.531e-03 infty:  2.548e-02
+Divergence time: 0.375 first:  8.226e-04 second:  1.536e-03 infty:  2.753e-02
+Divergence time: 0.38125 first:  8.227e-04 second:  1.518e-03 infty:  2.632e-02
+Divergence time: 0.3875 first:  8.149e-04 second:  1.505e-03 infty:  2.492e-02
+Divergence time: 0.39375 first:  8.184e-04 second:  1.520e-03 infty:  2.553e-02
+Divergence time: 0.4 first:  8.193e-04 second:  1.475e-03 infty:  1.910e-02
+Divergence time: 0.40625 first:  8.200e-04 second:  1.465e-03 infty:  1.951e-02
+Divergence time: 0.4125 first:  8.164e-04 second:  1.456e-03 infty:  1.895e-02
+Divergence time: 0.41875 first:  8.135e-04 second:  1.443e-03 infty:  1.957e-02
+Divergence time: 0.425 first:  8.127e-04 second:  1.429e-03 infty:  1.957e-02
+Divergence time: 0.43125 first:  8.198e-04 second:  1.454e-03 infty:  1.794e-02
+Divergence time: 0.4375 first:  8.240e-04 second:  1.462e-03 infty:  1.926e-02
+Divergence time: 0.44375 first:  8.286e-04 second:  1.467e-03 infty:  1.926e-02
+Divergence time: 0.45 first:  8.278e-04 second:  1.445e-03 infty:  1.747e-02
+Divergence time: 0.45625 first:  8.231e-04 second:  1.424e-03 infty:  1.747e-02
+Divergence time: 0.4625 first:  8.290e-04 second:  1.452e-03 infty:  1.547e-02
+Divergence time: 0.46875 first:  8.331e-04 second:  1.469e-03 infty:  1.554e-02
+Divergence time: 0.475 first:  8.335e-04 second:  1.465e-03 infty:  1.550e-02
+Divergence time: 0.48125 first:  8.338e-04 second:  1.468e-03 infty:  1.550e-02
+Divergence time: 0.4875 first:  8.342e-04 second:  1.475e-03 infty:  1.777e-02
+Divergence time: 0.49375 first:  8.343e-04 second:  1.493e-03 infty:  1.791e-02
+Divergence time: 0.5 first:  8.265e-04 second:  1.463e-03 infty:  1.790e-02
+Divergence time: 0.50625 first:  8.191e-04 second:  1.438e-03 infty:  2.093e-02
+Divergence time: 0.5125 first:  8.184e-04 second:  1.458e-03 infty:  2.484e-02
+Divergence time: 0.51875 first:  8.210e-04 second:  1.474e-03 infty:  2.794e-02
+Divergence time: 0.525 first:  8.175e-04 second:  1.447e-03 infty:  2.139e-02
+Divergence time: 0.53125 first:  8.194e-04 second:  1.451e-03 infty:  1.994e-02
+Divergence time: 0.5375 first:  8.268e-04 second:  1.478e-03 infty:  2.097e-02
+Divergence time: 0.54375 first:  8.307e-04 second:  1.482e-03 infty:  2.148e-02
+Divergence time: 0.55 first:  8.220e-04 second:  1.446e-03 infty:  2.210e-02
+Divergence time: 0.55625 first:  8.239e-04 second:  1.454e-03 infty:  2.207e-02
+Divergence time: 0.5625 first:  8.335e-04 second:  1.482e-03 infty:  2.064e-02
+Divergence time: 0.56875 first:  8.365e-04 second:  1.487e-03 infty:  2.236e-02
+Divergence time: 0.575 first:  8.399e-04 second:  1.480e-03 infty:  2.097e-02
+Divergence time: 0.58125 first:  8.450e-04 second:  1.500e-03 infty:  2.247e-02
+Divergence time: 0.5875 first:  8.515e-04 second:  1.520e-03 infty:  2.241e-02
+Divergence time: 0.59375 first:  8.471e-04 second:  1.514e-03 infty:  2.113e-02
+Divergence time: 0.6 first:  8.465e-04 second:  1.513e-03 infty:  2.257e-02
+Divergence time: 0.60625 first:  8.518e-04 second:  1.521e-03 infty:  2.128e-02
+Divergence time: 0.6125 first:  8.542e-04 second:  1.527e-03 infty:  2.256e-02
+Divergence time: 0.61875 first:  8.584e-04 second:  1.537e-03 infty:  2.095e-02
+Divergence time: 0.625 first:  8.609e-04 second:  1.547e-03 infty:  2.256e-02
+Divergence time: 0.63125 first:  8.574e-04 second:  1.533e-03 infty:  2.095e-02
+Divergence time: 0.6375 first:  8.567e-04 second:  1.541e-03 infty:  2.243e-02
+Divergence time: 0.64375 first:  8.579e-04 second:  1.533e-03 infty:  2.103e-02
+Divergence time: 0.65 first:  8.605e-04 second:  1.542e-03 infty:  2.245e-02
+Divergence time: 0.65625 first:  8.625e-04 second:  1.551e-03 infty:  2.086e-02
+Divergence time: 0.6625 first:  8.609e-04 second:  1.551e-03 infty:  2.234e-02
+Divergence time: 0.66875 first:  8.545e-04 second:  1.535e-03 infty:  2.230e-02
+Divergence time: 0.675 first:  8.635e-04 second:  1.553e-03 infty:  2.088e-02
+Divergence time: 0.68125 first:  8.622e-04 second:  1.547e-03 infty:  2.230e-02
+Divergence time: 0.6875 first:  8.573e-04 second:  1.532e-03 infty:  2.237e-02
+Divergence time: 0.69375 first:  8.597e-04 second:  1.535e-03 infty:  2.227e-02
+Divergence time: 0.7 first:  8.556e-04 second:  1.526e-03 infty:  2.078e-02
+Divergence time: 0.70625 first:  8.575e-04 second:  1.539e-03 infty:  2.234e-02
+Divergence time: 0.7125 first:  8.441e-04 second:  1.498e-03 infty:  2.102e-02
+Divergence time: 0.71875 first:  8.402e-04 second:  1.490e-03 infty:  2.255e-02
+Divergence time: 0.725 first:  8.374e-04 second:  1.482e-03 infty:  1.899e-02
+Divergence time: 0.73125 first:  8.356e-04 second:  1.478e-03 infty:  1.999e-02
+Divergence time: 0.7375 first:  8.267e-04 second:  1.445e-03 infty:  2.103e-02
+Divergence time: 0.74375 first:  8.226e-04 second:  1.441e-03 infty:  2.249e-02
+Divergence time: 0.75 first:  8.163e-04 second:  1.415e-03 infty:  2.265e-02
+Divergence time: 0.75625 first:  8.181e-04 second:  1.423e-03 infty:  1.974e-02
+Divergence time: 0.7625 first:  8.085e-04 second:  1.388e-03 infty:  2.137e-02
+Divergence time: 0.76875 first:  8.122e-04 second:  1.418e-03 infty:  2.285e-02
+Divergence time: 0.775 first:  8.116e-04 second:  1.410e-03 infty:  2.124e-02
+Divergence time: 0.78125 first:  8.019e-04 second:  1.392e-03 infty:  2.249e-02
+Divergence time: 0.7875 first:  7.892e-04 second:  1.355e-03 infty:  2.278e-02
+Divergence time: 0.79375 first:  7.878e-04 second:  1.354e-03 infty:  2.128e-02
+Divergence time: 0.8 first:  7.862e-04 second:  1.349e-03 infty:  2.284e-02
+Divergence time: 0.80625 first:  7.874e-04 second:  1.347e-03 infty:  1.923e-02
+Divergence time: 0.8125 first:  7.815e-04 second:  1.323e-03 infty:  2.100e-02
+Divergence time: 0.81875 first:  7.777e-04 second:  1.307e-03 infty:  2.132e-02
+Divergence time: 0.825 first:  7.771e-04 second:  1.317e-03 infty:  2.286e-02
+Divergence time: 0.83125 first:  7.727e-04 second:  1.295e-03 infty:  1.948e-02
+Divergence time: 0.8375 first:  7.689e-04 second:  1.279e-03 infty:  2.080e-02
+Divergence time: 0.84375 first:  7.644e-04 second:  1.264e-03 infty:  1.737e-02
+Divergence time: 0.85 first:  7.625e-04 second:  1.257e-03 infty:  2.134e-02
+Divergence time: 0.85625 first:  7.598e-04 second:  1.258e-03 infty:  2.273e-02
+Divergence time: 0.8625 first:  7.564e-04 second:  1.236e-03 infty:  1.931e-02
+Divergence time: 0.86875 first:  7.561e-04 second:  1.231e-03 infty:  1.951e-02
+Divergence time: 0.875 first:  7.547e-04 second:  1.228e-03 infty:  1.573e-02
+Divergence time: 0.88125 first:  7.588e-04 second:  1.243e-03 infty:  1.528e-02
+Divergence time: 0.8875 first:  7.605e-04 second:  1.256e-03 infty:  1.520e-02
+Divergence time: 0.89375 first:  7.595e-04 second:  1.248e-03 infty:  1.467e-02
+Divergence time: 0.9 first:  7.586e-04 second:  1.244e-03 infty:  1.360e-02
+Divergence time: 0.90625 first:  7.538e-04 second:  1.216e-03 infty:  1.379e-02
+Divergence time: 0.9125 first:  7.520e-04 second:  1.208e-03 infty:  1.277e-02
+Divergence time: 0.91875 first:  7.513e-04 second:  1.210e-03 infty:  1.384e-02
+Divergence time: 0.925 first:  7.552e-04 second:  1.237e-03 infty:  1.600e-02
+Divergence time: 0.93125 first:  7.568e-04 second:  1.246e-03 infty:  1.565e-02
+Divergence time: 0.9375 first:  7.590e-04 second:  1.244e-03 infty:  1.447e-02
+Divergence time: 0.94375 first:  7.533e-04 second:  1.218e-03 infty:  1.452e-02
+Divergence time: 0.95 first:  7.515e-04 second:  1.208e-03 infty:  1.448e-02
+Divergence time: 0.95625 first:  7.512e-04 second:  1.214e-03 infty:  1.352e-02
+Divergence time: 0.9625 first:  7.588e-04 second:  1.258e-03 infty:  1.600e-02
+Divergence time: 0.96875 first:  7.607e-04 second:  1.262e-03 infty:  1.571e-02
+Divergence time: 0.975 first:  7.603e-04 second:  1.254e-03 infty:  1.621e-02
+Divergence time: 0.98125 first:  7.574e-04 second:  1.229e-03 infty:  1.278e-02
+Divergence time: 0.9875 first:  7.529e-04 second:  1.216e-03 infty:  1.576e-02
+Divergence time: 0.99375 first:  7.524e-04 second:  1.219e-03 infty:  1.548e-02
+Divergence time: 1 first:  7.587e-04 second:  1.256e-03 infty:  1.549e-02
+Divergence time: 1.00625 first:  7.567e-04 second:  1.235e-03 infty:  1.400e-02
+Divergence time: 1.0125 first:  7.569e-04 second:  1.236e-03 infty:  1.456e-02
+Divergence time: 1.01875 first:  7.540e-04 second:  1.228e-03 infty:  1.551e-02
+Divergence time: 1.025 first:  7.597e-04 second:  1.254e-03 infty:  1.630e-02
+Divergence time: 1.03125 first:  7.604e-04 second:  1.249e-03 infty:  1.440e-02
+Divergence time: 1.0375 first:  7.608e-04 second:  1.257e-03 infty:  1.625e-02
+Divergence time: 1.04375 first:  7.610e-04 second:  1.255e-03 infty:  1.617e-02
+Divergence time: 1.05 first:  7.598e-04 second:  1.237e-03 infty:  1.281e-02
+Divergence time: 1.05625 first:  7.577e-04 second:  1.232e-03 infty:  1.636e-02
+Divergence time: 1.0625 first:  7.576e-04 second:  1.229e-03 infty:  1.429e-02
+Divergence time: 1.06875 first:  7.614e-04 second:  1.258e-03 infty:  1.608e-02
+Divergence time: 1.075 first:  7.578e-04 second:  1.241e-03 infty:  1.421e-02
+Divergence time: 1.08125 first:  7.587e-04 second:  1.229e-03 infty:  1.302e-02
+Divergence time: 1.0875 first:  7.578e-04 second:  1.229e-03 infty:  1.472e-02
+Divergence time: 1.09375 first:  7.579e-04 second:  1.229e-03 infty:  1.421e-02
+Divergence time: 1.1 first:  7.624e-04 second:  1.255e-03 infty:  1.604e-02
+Divergence time: 1.10625 first:  7.609e-04 second:  1.252e-03 infty:  1.630e-02
+Divergence time: 1.1125 first:  7.610e-04 second:  1.242e-03 infty:  1.424e-02
+Divergence time: 1.11875 first:  7.610e-04 second:  1.241e-03 infty:  1.577e-02
+Divergence time: 1.125 first:  7.612e-04 second:  1.239e-03 infty:  1.410e-02
+Divergence time: 1.13125 first:  7.624e-04 second:  1.247e-03 infty:  1.433e-02
+Divergence time: 1.1375 first:  7.630e-04 second:  1.255e-03 infty:  1.419e-02
+Divergence time: 1.14375 first:  7.598e-04 second:  1.242e-03 infty:  1.472e-02
+Divergence time: 1.15 first:  7.624e-04 second:  1.243e-03 infty:  1.308e-02
+Divergence time: 1.15625 first:  7.612e-04 second:  1.238e-03 infty:  1.453e-02
+Divergence time: 1.1625 first:  7.632e-04 second:  1.241e-03 infty:  1.322e-02
+Divergence time: 1.16875 first:  7.641e-04 second:  1.255e-03 infty:  1.628e-02
+Divergence time: 1.175 first:  7.635e-04 second:  1.256e-03 infty:  1.427e-02
+Divergence time: 1.18125 first:  7.619e-04 second:  1.239e-03 infty:  1.459e-02
+Divergence time: 1.1875 first:  7.623e-04 second:  1.244e-03 infty:  1.353e-02
+Divergence time: 1.19375 first:  7.641e-04 second:  1.248e-03 infty:  1.430e-02
+Divergence time: 1.2 first:  7.698e-04 second:  1.282e-03 infty:  1.601e-02
+Divergence time: 1.20625 first:  7.658e-04 second:  1.261e-03 infty:  1.464e-02
+Divergence time: 1.2125 first:  7.661e-04 second:  1.255e-03 infty:  1.373e-02
+Divergence time: 1.21875 first:  7.632e-04 second:  1.242e-03 infty:  1.452e-02
+Divergence time: 1.225 first:  7.624e-04 second:  1.241e-03 infty:  1.397e-02
+Divergence time: 1.23125 first:  7.643e-04 second:  1.254e-03 infty:  1.633e-02
+Divergence time: 1.2375 first:  7.703e-04 second:  1.292e-03 infty:  1.582e-02
+Divergence time: 1.24375 first:  7.660e-04 second:  1.261e-03 infty:  1.449e-02
+Divergence time: 1.25 first:  7.673e-04 second:  1.274e-03 infty:  1.556e-02
+Divergence time: 1.25625 first:  7.634e-04 second:  1.244e-03 infty:  1.520e-02
+Divergence time: 1.2625 first:  7.677e-04 second:  1.267e-03 infty:  1.524e-02
+Divergence time: 1.26875 first:  7.667e-04 second:  1.278e-03 infty:  2.056e-02
+Divergence time: 1.275 first:  7.694e-04 second:  1.294e-03 infty:  1.673e-02
+Divergence time: 1.28125 first:  7.641e-04 second:  1.266e-03 infty:  1.632e-02
+Divergence time: 1.2875 first:  7.648e-04 second:  1.261e-03 infty:  1.633e-02
+Divergence time: 1.29375 first:  7.635e-04 second:  1.250e-03 infty:  1.563e-02
+Divergence time: 1.3 first:  7.666e-04 second:  1.256e-03 infty:  1.557e-02
+Divergence time: 1.30625 first:  7.665e-04 second:  1.280e-03 infty:  2.082e-02
+Divergence time: 1.3125 first:  7.655e-04 second:  1.286e-03 infty:  1.676e-02
+Divergence time: 1.31875 first:  7.611e-04 second:  1.258e-03 infty:  1.614e-02
+Divergence time: 1.325 first:  7.614e-04 second:  1.248e-03 infty:  1.635e-02
+Divergence time: 1.33125 first:  7.656e-04 second:  1.266e-03 infty:  1.595e-02
+Divergence time: 1.3375 first:  7.676e-04 second:  1.287e-03 infty:  2.150e-02
+Divergence time: 1.34375 first:  7.685e-04 second:  1.307e-03 infty:  2.335e-02
+Divergence time: 1.35 first:  7.623e-04 second:  1.279e-03 infty:  1.686e-02
+Divergence time: 1.35625 first:  7.627e-04 second:  1.263e-03 infty:  1.669e-02
+Divergence time: 1.3625 first:  7.623e-04 second:  1.267e-03 infty:  2.058e-02
+Divergence time: 1.36875 first:  7.703e-04 second:  1.316e-03 infty:  2.621e-02
+Divergence time: 1.375 first:  7.625e-04 second:  1.283e-03 infty:  2.302e-02
+Divergence time: 1.38125 first:  7.612e-04 second:  1.277e-03 infty:  2.312e-02
+Divergence time: 1.3875 first:  7.616e-04 second:  1.274e-03 infty:  1.749e-02
+Divergence time: 1.39375 first:  7.676e-04 second:  1.300e-03 infty:  2.025e-02
+Divergence time: 1.4 first:  7.658e-04 second:  1.278e-03 infty:  2.107e-02
+Divergence time: 1.40625 first:  7.740e-04 second:  1.327e-03 infty:  2.728e-02
+Divergence time: 1.4125 first:  7.679e-04 second:  1.312e-03 infty:  2.339e-02
+Divergence time: 1.41875 first:  7.712e-04 second:  1.317e-03 infty:  2.323e-02
+Divergence time: 1.425 first:  7.699e-04 second:  1.299e-03 infty:  2.094e-02
+Divergence time: 1.43125 first:  7.731e-04 second:  1.322e-03 infty:  2.427e-02
+Divergence time: 1.4375 first:  7.661e-04 second:  1.291e-03 infty:  2.602e-02
+Divergence time: 1.44375 first:  7.730e-04 second:  1.314e-03 infty:  2.153e-02
+Divergence time: 1.45 first:  7.750e-04 second:  1.320e-03 infty:  2.278e-02
+Divergence time: 1.45625 first:  7.662e-04 second:  1.276e-03 infty:  2.261e-02
+Divergence time: 1.4625 first:  7.733e-04 second:  1.314e-03 infty:  2.136e-02
+Divergence time: 1.46875 first:  7.730e-04 second:  1.324e-03 infty:  2.462e-02
+Divergence time: 1.475 first:  7.730e-04 second:  1.318e-03 infty:  2.205e-02
+Divergence time: 1.48125 first:  7.757e-04 second:  1.330e-03 infty:  2.435e-02
+Divergence time: 1.4875 first:  7.774e-04 second:  1.327e-03 infty:  2.437e-02
+Divergence time: 1.49375 first:  7.748e-04 second:  1.320e-03 infty:  2.445e-02
+Divergence time: 1.5 first:  7.711e-04 second:  1.300e-03 infty:  2.287e-02
+Divergence time: 1.50625 first:  7.707e-04 second:  1.291e-03 infty:  2.225e-02
+Divergence time: 1.5125 first:  7.743e-04 second:  1.303e-03 infty:  2.002e-02
+Divergence time: 1.51875 first:  7.755e-04 second:  1.307e-03 infty:  2.237e-02
+Divergence time: 1.525 first:  7.797e-04 second:  1.330e-03 infty:  2.500e-02
+Divergence time: 1.53125 first:  7.718e-04 second:  1.294e-03 infty:  2.381e-02
+Divergence time: 1.5375 first:  7.656e-04 second:  1.279e-03 infty:  2.373e-02
+Divergence time: 1.54375 first:  7.730e-04 second:  1.309e-03 infty:  2.298e-02
+Divergence time: 1.55 first:  7.745e-04 second:  1.304e-03 infty:  2.060e-02
+Divergence time: 1.55625 first:  7.767e-04 second:  1.317e-03 infty:  2.357e-02
+Divergence time: 1.5625 first:  7.786e-04 second:  1.323e-03 infty:  2.300e-02
+Divergence time: 1.56875 first:  7.831e-04 second:  1.317e-03 infty:  1.904e-02
+Divergence time: 1.575 first:  7.842e-04 second:  1.317e-03 infty:  2.075e-02
+Divergence time: 1.58125 first:  7.804e-04 second:  1.307e-03 infty:  2.301e-02
+Divergence time: 1.5875 first:  7.821e-04 second:  1.332e-03 infty:  2.313e-02
+Divergence time: 1.59375 first:  7.879e-04 second:  1.358e-03 infty:  2.275e-02
+Divergence time: 1.6 first:  7.933e-04 second:  1.361e-03 infty:  2.077e-02
+Divergence time: 1.60625 first:  7.996e-04 second:  1.387e-03 infty:  2.447e-02
+Divergence time: 1.6125 first:  7.992e-04 second:  1.374e-03 infty:  2.071e-02
+Divergence time: 1.61875 first:  8.022e-04 second:  1.391e-03 infty:  2.261e-02
+Divergence time: 1.625 first:  8.025e-04 second:  1.394e-03 infty:  2.317e-02
+Divergence time: 1.63125 first:  8.036e-04 second:  1.382e-03 infty:  2.177e-02
+Divergence time: 1.6375 first:  8.035e-04 second:  1.380e-03 infty:  2.134e-02
+Divergence time: 1.64375 first:  8.013e-04 second:  1.363e-03 infty:  2.309e-02
+Divergence time: 1.65 first:  8.016e-04 second:  1.373e-03 infty:  2.196e-02
+Divergence time: 1.65625 first:  8.041e-04 second:  1.401e-03 infty:  2.460e-02
+Divergence time: 1.6625 first:  8.098e-04 second:  1.404e-03 infty:  2.060e-02
+Divergence time: 1.66875 first:  8.177e-04 second:  1.427e-03 infty:  2.170e-02
+Divergence time: 1.675 first:  8.177e-04 second:  1.424e-03 infty:  2.451e-02
+Divergence time: 1.68125 first:  8.197e-04 second:  1.415e-03 infty:  2.015e-02
+Divergence time: 1.6875 first:  8.183e-04 second:  1.425e-03 infty:  2.474e-02
+Divergence time: 1.69375 first:  8.156e-04 second:  1.422e-03 infty:  2.258e-02
+Divergence time: 1.7 first:  8.192e-04 second:  1.438e-03 infty:  2.105e-02
+Divergence time: 1.70625 first:  8.162e-04 second:  1.425e-03 infty:  2.302e-02
+Divergence time: 1.7125 first:  8.208e-04 second:  1.443e-03 infty:  2.421e-02
+Divergence time: 1.71875 first:  8.197e-04 second:  1.437e-03 infty:  2.259e-02
+Divergence time: 1.725 first:  8.229e-04 second:  1.434e-03 infty:  2.132e-02
+Divergence time: 1.73125 first:  8.225e-04 second:  1.429e-03 infty:  2.394e-02
+Divergence time: 1.7375 first:  8.277e-04 second:  1.439e-03 infty:  2.113e-02
+Divergence time: 1.74375 first:  8.321e-04 second:  1.443e-03 infty:  2.285e-02
+Divergence time: 1.75 first:  8.300e-04 second:  1.442e-03 infty:  2.148e-02
+Divergence time: 1.75625 first:  8.250e-04 second:  1.437e-03 infty:  2.399e-02
+Divergence time: 1.7625 first:  8.304e-04 second:  1.447e-03 infty:  2.015e-02
+Divergence time: 1.76875 first:  8.335e-04 second:  1.454e-03 infty:  2.180e-02
+Divergence time: 1.775 first:  8.327e-04 second:  1.458e-03 infty:  2.066e-02
+Divergence time: 1.78125 first:  8.380e-04 second:  1.474e-03 infty:  2.222e-02
+Divergence time: 1.7875 first:  8.352e-04 second:  1.469e-03 infty:  2.347e-02
+Divergence time: 1.79375 first:  8.347e-04 second:  1.470e-03 infty:  2.147e-02
+Divergence time: 1.8 first:  8.325e-04 second:  1.463e-03 infty:  2.328e-02
+Divergence time: 1.80625 first:  8.356e-04 second:  1.461e-03 infty:  2.268e-02
+Divergence time: 1.8125 first:  8.382e-04 second:  1.465e-03 infty:  2.072e-02
+Divergence time: 1.81875 first:  8.363e-04 second:  1.456e-03 infty:  2.112e-02
+Divergence time: 1.825 first:  8.356e-04 second:  1.456e-03 infty:  2.174e-02
+Divergence time: 1.83125 first:  8.348e-04 second:  1.453e-03 infty:  2.134e-02
+Divergence time: 1.8375 first:  8.314e-04 second:  1.440e-03 infty:  2.257e-02
+Divergence time: 1.84375 first:  8.289e-04 second:  1.447e-03 infty:  2.172e-02
+Divergence time: 1.85 first:  8.193e-04 second:  1.432e-03 infty:  2.317e-02
+Divergence time: 1.85625 first:  8.177e-04 second:  1.423e-03 infty:  2.172e-02
+Divergence time: 1.8625 first:  8.210e-04 second:  1.430e-03 infty:  2.306e-02
+Divergence time: 1.86875 first:  8.263e-04 second:  1.442e-03 infty:  1.955e-02
+Divergence time: 1.875 first:  8.306e-04 second:  1.452e-03 infty:  2.101e-02
+Divergence time: 1.88125 first:  8.289e-04 second:  1.456e-03 infty:  2.123e-02
+Divergence time: 1.8875 first:  8.262e-04 second:  1.447e-03 infty:  2.334e-02
+Divergence time: 1.89375 first:  8.221e-04 second:  1.439e-03 infty:  2.264e-02
+Divergence time: 1.9 first:  8.177e-04 second:  1.446e-03 infty:  2.379e-02
+Divergence time: 1.90625 first:  8.200e-04 second:  1.447e-03 infty:  2.128e-02
+Divergence time: 1.9125 first:  8.206e-04 second:  1.440e-03 infty:  2.207e-02
+Divergence time: 1.91875 first:  8.191e-04 second:  1.424e-03 infty:  2.264e-02
+Divergence time: 1.925 first:  8.226e-04 second:  1.429e-03 infty:  1.924e-02
+Divergence time: 1.93125 first:  8.219e-04 second:  1.448e-03 infty:  2.257e-02
+Divergence time: 1.9375 first:  8.170e-04 second:  1.428e-03 infty:  2.267e-02
+Divergence time: 1.94375 first:  8.118e-04 second:  1.417e-03 infty:  2.399e-02
+Divergence time: 1.95 first:  8.038e-04 second:  1.411e-03 infty:  2.370e-02
+Divergence time: 1.95625 first:  8.008e-04 second:  1.410e-03 infty:  2.524e-02
+Divergence time: 1.9625 first:  8.051e-04 second:  1.398e-03 infty:  2.086e-02
+Divergence time: 1.96875 first:  8.056e-04 second:  1.397e-03 infty:  2.082e-02
+Divergence time: 1.975 first:  8.037e-04 second:  1.385e-03 infty:  2.171e-02
+Divergence time: 1.98125 first:  8.056e-04 second:  1.393e-03 infty:  2.135e-02
+Divergence time: 1.9875 first:  8.036e-04 second:  1.382e-03 infty:  2.251e-02
+Divergence time: 1.99375 first:  8.021e-04 second:  1.385e-03 infty:  2.247e-02
+Divergence time: 2 first:  7.973e-04 second:  1.369e-03 infty:  2.366e-02
diff --git a/test/reynolds/reynolds.gfs b/test/reynolds/reynolds.gfs
new file mode 100644
index 0000000..01efb55
--- /dev/null
+++ b/test/reynolds/reynolds.gfs
@@ -0,0 +1,72 @@
+# Title: Estimation of the numerical viscosity
+#
+# Description:
+#
+# The velocity field is initialised with an exact stationary solution of
+# the Euler equations in a periodic 2D domain. An exact Euler solver
+# would not change this field, however any numerical solver will
+# introduce numerical dissipation which will slowly dissipate the
+# kinetic energy of the initial solution. By monitoring the evolution of
+# the kinetic energy, the dissipative properties of the numerical scheme
+# can be measured (see \cite{rider95} for details).
+#
+# Figures \ref{divmax} and figure \ref{divL2} illustrate the evolution
+# of the divergence of the velocity field with time. This is a check of
+# the stability of the approximate projection and should remain bounded.
+#
+# Figures \ref{kinetic} and \ref{reynolds} illustrates the evolution of
+# the kinetic energy and the corresponding equivalent Reynolds number as
+# a function of resolution. The higher the Reynolds number, the less
+# dissipative the scheme.
+#
+# \begin{figure}[htbp]
+# \caption{\label{divmax}Evolution of the maximum divergence.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{divmax.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{divL2}Evolution of the L2 norm of the divergence.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{divL2.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{kinetic}Evolution of the kinetic energy.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{kinetic.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{reynolds}Equivalent Reynolds number as a function of resolution.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{reynolds.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh reynolds.sh reynolds.gfs 1
+# Version: 0.6.4
+# Required files: reynolds.sh div5.ref div6.ref div7.ref reynolds.ref
+# Running time: 3 minutes
+# Generated files: divmax.eps reynolds.eps divL2.eps kinetic.eps
+#
+1 2 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = 2 }
+  Refine LEVEL
+  Init {} {
+    U = (- cos (2.*M_PI*x)*sin (2.*M_PI*y))
+    V = (sin (2.*M_PI*x)*cos (2.*M_PI*y))
+  }
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  OutputScalarNorm { istep = 1 } divLEVEL { v = Divergence }
+  OutputScalarSum { istep = 1 } kineticLEVEL { v = Velocity2 }
+  OutputScalarSum { istep = 1 } stdout { v = Velocity2 }
+}
+GfsBox {}
+1 1 right
+1 1 top
diff --git a/test/reynolds/reynolds.ref b/test/reynolds/reynolds.ref
new file mode 100644
index 0000000..a730684
--- /dev/null
+++ b/test/reynolds/reynolds.ref
@@ -0,0 +1,3 @@
+5 9981.15
+6 79608.4
+7 637877
diff --git a/test/reynolds/reynolds.sh b/test/reynolds/reynolds.sh
new file mode 100644
index 0000000..7ba4a92
--- /dev/null
+++ b/test/reynolds/reynolds.sh
@@ -0,0 +1,53 @@
+if ! $donotrun; then
+    rm -f reynolds
+
+    for level in 5 6 7; do
+	if sed "s/LEVEL/$level/g" < $1 | gerris2D - | awk -v m=$2 -v level=$level '{
+          time = $3
+          ke = $5
+          if (time == 0)
+            ke0 = ke;
+          }END{
+            a = -log(ke/ke0)/time
+            nu = a/(4.*(2.*m*3.14159265359)^2)
+            print level " " 1./nu
+          }' >> reynolds; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'divmax.eps'
+    set xlabel 'Time'
+    set ylabel 'Divergence Max'
+    plot [0:2]'div5' u 3:9 t "5" w l, 'div6' u 3:9 t "6" w l, 'div7' u 3:9 t "7" w l, 'div5.ref' u 3:9 t "5 (ref)" w l, 'div6.ref' u 3:9 t "6 (ref)" w l, 'div7.ref' u 3:9 t "7 (ref)" w l
+    set output 'divL2.eps'
+    set ylabel 'Divergence L2'
+    plot [0:2]'div5' u 3:7 t "5" w l, 'div6' u 3:7 t "6" w l, 'div7' u 3:7 t "7" w l, 'div5.ref' u 3:7 t "5 (ref)" w l, 'div6.ref' u 3:7 t "6 (ref)" w l, 'div7.ref' u 3:7 t "7 (ref)" w l
+    set output 'kinetic.eps'
+    set ylabel 'Kinetic energy'
+    plot [0:2]'kinetic5' u 3:5 t "5" w l, 'kinetic6' u 3:5 t "6" w l, 'kinetic7' u 3:5 t "7" w l
+    set output 'reynolds.eps'
+    set xlabel 'Level'
+    set ylabel 'Effective Reynolds number'
+    set logscale y
+    plot 'reynolds' u 1:2 t "" w lp, 'reynolds.ref' u 1:2 t "ref" w lp
+EOF
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+for div in ['div5','div6','div7']:
+  if (Curve(div,3,9) - Curve(div+'.ref',3,9)).max() > 0.01*Curve(div+'.ref',3,9).mean() or\
+     (Curve(div,3,7) - Curve(div+'.ref',3,7)).max() > 0.01*Curve(div+'.ref',3,7).mean():
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/shear/curvature/curvature.gfs b/test/shear/curvature/curvature.gfs
new file mode 100644
index 0000000..3166e1b
--- /dev/null
+++ b/test/shear/curvature/curvature.gfs
@@ -0,0 +1,91 @@
+# Title: Time-reversed advection with curvature-based refinement
+#
+# Description:
+#
+# Same as the previous test but with adaptivity based on the local
+# curvature of the interface (with a maximum of eight levels of
+# refinement).
+#
+# \begin{figure}[htbp]
+# \caption{\label{advection}Interface shape and refined mesh at time 2.5.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{t-2.5.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Difference between the initial and final volume fraction fields.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{dt-5.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{table}[htbp]
+# \caption{\label{norms}Norms of the error between the initial and final fields. The
+# reference values are given in blue.}
+# \begin{center}
+# \begin{tabular}{|c|c|c|}\hline
+# $L_1$ & $L_2$ & $L_\infty$ \\ \hline
+# \input{norms.tex}
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../shear.sh curvature.gfs | gfsview-batch2D curvature.gfv
+# Version: 091022
+# Required files: ../shear.sh norms.ref curvature.gfv
+# Running time: 2 minutes
+# Generated files: t-2.5.eps dt-5.eps norms norms.tex
+#
+# The type of the simulation is GfsAdvection which only solves the advection
+# of passive tracers.
+1 0 GfsAdvection GfsBox GfsGEdge {} {
+    Time { end = 5 }
+    Refine 8
+
+    # Add tracer T, using a VOF advection scheme.
+    # The default scheme is a Van-Leer limited, second-order upwind scheme.
+    VariableTracerVOF T
+
+    # Curvature K of the interface defined by T
+    VariableCurvature K T
+
+    InitFraction T (ellipse (0, -.236338, 0.2, 0.2))
+
+    # Maintain U and V with the vortical shear flow field defined by
+    # its streamfunction
+    VariableStreamFunction {
+	# make sure that the entire field is reinitialised at t = 2.5
+	step = 2.5 
+    } Psi (t < 2.5 ? 1. : -1.)*sin((x + 0.5)*M_PI)*sin((y + 0.5)*M_PI)/M_PI
+    
+    # Adapt the mesh dynamically using a custom cost function returning
+    # the cell size times the local curvature (only for cells cut by
+    # the interface).
+    # The maximum cost is set to 0.1 i.e. the radius of curvature must be
+    # resolved with at least 10 cells.
+    AdaptFunction { istep = 1 } { cmax = 0.1 maxlevel = 8 } {
+        return T > 0. && T < 1. ? ftt_cell_size (cell)*fabs (K) : 0.;
+    }
+
+    OutputSimulation { start = 2.5 } stdout
+    EventScript { start = 2.5 } { echo "Save t-2.5.eps { format = EPS line_width = 0.5 }" }
+    
+    # Add a new variable 
+    Variable Tref
+
+    # Initialize Tref with the initial shape
+    InitFraction { start = end } Tref (ellipse (0, -.236338, 0.2, 0.2))
+
+    # Output the norms of the difference between T and Tref, stores that into
+    # new variable DT
+    OutputErrorNorm { start = end } norms { v = T } {
+        s = Tref v = DT
+    }
+
+    OutputPPM { start = end } { convert ppm:- dt-5.eps } { v = DT }
+
+    OutputScalarSum { istep = 1 } { awk '{ print $3,$5-8.743441e-01 }' > t } { v = T }
+}
+GfsBox {}
diff --git a/test/shear/curvature/curvature.gfv b/test/shear/curvature/curvature.gfv
new file mode 100644
index 0000000..d4439d2
--- /dev/null
+++ b/test/shear/curvature/curvature.gfv
@@ -0,0 +1,35 @@
+# GfsView 2D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 24.9119
+  r = 1 g = 1 b = 1
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Cells {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+}
+VOF {
+  r = 0.010071 g = 0 b = 1
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} T {
+  reversed = 0
+  use_scalar = 0
+  draw_edges = 0
+}
diff --git a/test/shear/curvature/norms.ref b/test/shear/curvature/norms.ref
new file mode 100644
index 0000000..33cfacd
--- /dev/null
+++ b/test/shear/curvature/norms.ref
@@ -0,0 +1 @@
+T time: 5 first:  9.417e-04 second:  1.027e-02 infty:  4.270e-01 bias: -4.640e-05
diff --git a/test/shear/norms.ref b/test/shear/norms.ref
new file mode 100644
index 0000000..96996bf
--- /dev/null
+++ b/test/shear/norms.ref
@@ -0,0 +1 @@
+T time: 5 first:  1.734e-04 second:  5.716e-03 infty:  3.770e-01 bias:  1.053e-05
diff --git a/test/shear/shear.gfs b/test/shear/shear.gfs
new file mode 100644
index 0000000..3937a0c
--- /dev/null
+++ b/test/shear/shear.gfs
@@ -0,0 +1,98 @@
+# Title: Time-reversed VOF advection in a shear flow
+#
+# Description:
+#
+# A test case initially presented by Rudman \cite{rudman97}.
+# A circular patch of tracer is advected in a vortical shear flow. At t = 2.5
+# the flow direction is reversed. An exact advection scheme would restore the 
+# initial circular shape at t = 5.
+#
+# The VOF (Volume-Of-Fluid) advection scheme is not exact. The initial, intermediate
+# and final shape of the interface are represented on Figure \ref{advection}. 
+# Figure \ref{error} illustrates the error between the initial and final shapes. The
+# corresponding error norms are given in Table \ref{norms}.
+#
+# Adaptive refinement is used with the gradient of the volume fraction as criterion.
+# Eight levels of refinement are used on the interfaces and six away from the interface.
+#
+# \begin{figure}[htbp]
+# \caption{\label{advection}Volume fraction field at times (a) 0, (b) 2.5 and (c) 5.}
+# \begin{center}
+# \begin{tabular}{ccc}
+# \includegraphics[width=0.3\hsize]{t-0.eps} &
+# \includegraphics[width=0.3\hsize]{t-2.5.eps} &
+# \includegraphics[width=0.3\hsize]{t-5.eps} \\
+# (a) & (b) & (c)
+# \end{tabular}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{error}Difference between the initial and final volume fraction fields.}
+# \begin{center}
+# \includegraphics[width=0.4\hsize]{dt-5.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{table}[htbp]
+# \caption{\label{norms}Norms of the error between the initial and final fields. The
+# reference values are given in blue.}
+# \begin{center}
+# \begin{tabular}{|c|c|c|}\hline
+# $L_1$ & $L_2$ & $L_\infty$ \\ \hline
+# \input{norms.tex}
+# \end{tabular}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh shear.sh shear.gfs
+# Version: 091022
+# Required files: shear.sh norms.ref
+# Running time: 2 minutes
+# Generated files: t-0.eps t-2.5.eps t-5.eps dt-5.eps norms norms.tex
+#
+# The type of the simulation is GfsAdvection which only solves the advection
+# of passive tracers.
+1 0 GfsAdvection GfsBox GfsGEdge {} {
+    Time { end = 5 }
+    Refine 8
+
+    # Add tracer T, using a VOF advection scheme.
+    # The default scheme is a Van-Leer limited, second-order upwind scheme.
+    VariableTracerVOF T
+
+    InitFraction T (ellipse (0, -.236338, 0.2, 0.2))
+
+    # Maintain U and V with the vortical shear flow field defined by
+    # its streamfunction
+    VariableStreamFunction {
+	# make sure that the entire field is reinitialised at t = 2.5
+	step = 2.5 
+    } Psi (t < 2.5 ? 1. : -1.)*sin((x + 0.5)*M_PI)*sin((y + 0.5)*M_PI)/M_PI
+    
+    # Adapt the mesh dynamically so that at any time the maximum of the gradient
+    # of T is less than 1e-2 per cell length
+    AdaptGradient { istep = 1 } { cmax = 1e-2 maxlevel = 8 } T
+    
+    OutputPPM { start = 0 } { convert ppm:- t-0.eps } { v = T }
+    OutputPPM { start = 2.5 } { convert ppm:- t-2.5.eps } { v = T }
+    OutputPPM { start = 5 } { convert ppm:- t-5.eps } { v = T }
+
+    # Add a new variable 
+    Variable Tref
+
+    # Initialize Tref with the initial shape
+    InitFraction { start = end } Tref (ellipse (0, -.236338, 0.2, 0.2))
+
+    # Output the norms of the difference between T and Tref, stores that into
+    # new variable DT
+    OutputErrorNorm { start = end } norms { v = T } {
+        s = Tref v = DT
+    }
+
+    OutputPPM { start = end } { convert ppm:- dt-5.eps } { v = DT }
+
+    OutputScalarSum { istep = 1 } { awk '{ print $3,$5-8.743441e-01 }' > t } { v = T }
+}
+GfsBox {}
diff --git a/test/shear/shear.sh b/test/shear/shear.sh
new file mode 100644
index 0000000..9504cfd
--- /dev/null
+++ b/test/shear/shear.sh
@@ -0,0 +1,27 @@
+if ! $donotrun; then
+    if gerris2D $1; then :
+    else
+	exit 1
+    fi
+fi
+
+if awk '{print $5 " & " $7 " & " $9 "\\\\"}' < norms > norms.tex && \
+   awk '{print "{\\color{blue}" $5 "} & {\\color{blue}" $7 "} & {\\color{blue}" $9 "}"}' < norms.ref >> norms.tex ; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('norms',3,5) - Curve('norms.ref',3,5)).max() > 0. or\
+   (Curve('norms',3,7) - Curve('norms.ref',3,7)).max() > 0. or\
+   (Curve('norms',3,9) - Curve('norms.ref',3,9)).max() > 0. or\
+   (Curve('norms',3,11) - Curve('norms.ref',3,11)).max() > 0.:
+    exit(1)
+if Curve('t',1,2).max() > 2e-5:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/spurious/axi/axi.gfs b/test/spurious/axi/axi.gfs
new file mode 100644
index 0000000..3303a1d
--- /dev/null
+++ b/test/spurious/axi/axi.gfs
@@ -0,0 +1,93 @@
+# Title: Axisymmetric spherical droplet in equilibrium
+#
+# Description:
+#
+# The same test case but using the axisymmetric solver. The results
+# are comparable.
+#
+# \begin{figure}[htbp]
+# \caption{\label{laplace}Evolution of the amplitude of the capillary currents
+# $\max(|{\bf u}|)(D/\sigma)^{1/2}$ as a function of
+# non-dimensional time $\tau=t\mu/D^2$ for the range of Laplace
+# numbers indicated in the legend.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{laplace.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{curvature}Evolution of the standard deviation of the
+# value of the curvature along the interface as a function of
+# non-dimensional time $\tau=t\mu/D^2$ for the range of Laplace
+# numbers indicated in the legend.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{curvature.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{convergence}Convergence of the error on the equilibrium shape of the
+# droplet with resolution. The diameter is given in number of grid
+# points.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{convergence.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{kconvergence}Convergence of the relative error on the
+# equilibrium curvature value with resolution. The diameter is given
+# in number of grid points.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{kconvergence.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../spurious.sh axi.gfs 1e-7
+# Version: 1.3.1
+# Required files: convergence.ref kconvergence.ref
+# Generated files: laplace.eps curvature.eps convergence.eps kconvergence.eps
+#
+
+Define CIRCLE (ellipse (-0.5,0.,0.4,0.4))
+Define MU sqrt(0.8/LAPLACE)
+
+1 0 GfsAxi GfsBox GfsGEdge {} {
+  Time { end = TMAX }
+  Refine LEVEL
+  RefineSurface {return 10;} CIRCLE
+
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  AdvectionParams { scheme = none }
+
+  VariableTracerVOF T
+  VariableCurvature K T
+  SourceTension T 1 K
+  SourceViscosity MU
+
+  InitFraction T CIRCLE
+  Init {} { Tref = T }
+
+  AdaptGradient { istep = 1 } { cmax = 1e-6 maxlevel = LEVEL } T
+  EventStop { istep = 10 } T DT
+
+  OutputSimulation { start = end } stdout { depth = LEVEL }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $9*sqrt(0.8); fflush (stdout); }' > La-LAPLACE-LEVEL
+  } { v = Velocity }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9; fflush (stdout); }' > E-LAPLACE-LEVEL
+  } { v = (Tref - T) }
+  OutputScalarStats { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9, $11; fflush (stdout); }' > K-LAPLACE-LEVEL
+  } { v = (K - 2.50771) }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9; fflush (stdout); }' > EK-LAPLACE-LEVEL
+  } { v = (T > 0 && T < 1 ? (K - 5.)/2. : 0) }
+}
+GfsBox {
+  bottom = Boundary
+  left = Boundary
+}
diff --git a/test/spurious/axi/convergence.ref b/test/spurious/axi/convergence.ref
new file mode 100644
index 0000000..80168d7
--- /dev/null
+++ b/test/spurious/axi/convergence.ref
@@ -0,0 +1,5 @@
+6.4 5.024e-03 6.003e-02
+12.8 2.638e-03 3.845e-02
+25.6 9.115e-04 1.646e-02
+51.2 2.468e-04 7.265e-03
+102.4 9.238e-05 3.723e-03
diff --git a/test/spurious/axi/kconvergence.ref b/test/spurious/axi/kconvergence.ref
new file mode 100644
index 0000000..3fdf3b7
--- /dev/null
+++ b/test/spurious/axi/kconvergence.ref
@@ -0,0 +1,5 @@
+6.4 0.010728 0.04292
+12.8 0.0014968 0.00882
+25.6 0.00033816 0.0029452
+51.2 4.72e-05 0.0005896
+102.4 9.3e-06 0.00016372
diff --git a/test/spurious/convergence.ref b/test/spurious/convergence.ref
new file mode 100644
index 0000000..ec86d3e
--- /dev/null
+++ b/test/spurious/convergence.ref
@@ -0,0 +1,5 @@
+6.4 3.527e-02 2.461e-01
+12.8 3.735e-04 4.232e-03
+25.6 9.049e-05 1.263e-03
+51.2 2.475e-05 4.603e-04
+102.4 8.812e-06 2.312e-04
diff --git a/test/spurious/kconvergence.ref b/test/spurious/kconvergence.ref
new file mode 100644
index 0000000..fe49a7b
--- /dev/null
+++ b/test/spurious/kconvergence.ref
@@ -0,0 +1,5 @@
+6.4 0.05632 0.15016
+12.8 0.002922 0.012968
+25.6 0.00049 0.0030176
+51.2 8.136e-05 0.0007292
+102.4 1.4608e-05 0.00018448
diff --git a/test/spurious/spurious.gfs b/test/spurious/spurious.gfs
new file mode 100644
index 0000000..7da7160
--- /dev/null
+++ b/test/spurious/spurious.gfs
@@ -0,0 +1,117 @@
+# Title: Circular droplet in equilibrium
+#
+# Description:
+#
+# A circular droplet of diameter $D=0.8$ is initialised centered on
+# the top-left corner of the unit box. Surface tension is imposed on
+# the interface. The exact solution is given by Laplace's law: uniform
+# zero velocity and a pressure jump accross the interface exactly
+# balancing the surface tension force.
+#
+# The initial condition -- while close to the exact solution -- does
+# not guarantee the exact balance between the numerical
+# discretisations of surface tension and pressure gradient. However,
+# these small initial perturbations generate small capillary waves
+# which are progressively (on a timescale of order $D^2/\mu$) damped
+# by viscosity so that the exact (to round-off error) balance is
+# eventually obtained.
+#
+# The convergence is obtained for a wide range of Laplace numbers
+# $La=\sigma\rho D/\mu^2$, as illustrated on Figure \ref{laplace}.
+# Correspondingly, convergence of the curvature to a constant value is
+# also obtained at all Laplace numbers as illustrated on Figure
+# \ref{curvature}.
+#
+# Figure \ref{convergence} illustrates the convergence of the error on
+# the droplet shape as a function of resolution for a Laplace number
+# of 12000. Both the shape error and the relative error on the
+# equilibrium curvature value illustrated on Figure
+# \ref{kconvergence} show close to second-order convergence.
+#
+# \begin{figure}[htbp]
+# \caption{\label{laplace}Evolution of the amplitude of the capillary currents
+# $\max(|{\bf u}|)(D/\sigma)^{1/2}$ as a function of
+# non-dimensional time $\tau=t\mu/D^2$ for the range of Laplace
+# numbers indicated in the legend.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{laplace.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{curvature}Evolution of the standard deviation of the
+# value of the curvature along the interface as a function of
+# non-dimensional time $\tau=t\mu/D^2$ for the range of Laplace
+# numbers indicated in the legend.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{curvature.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{convergence}Convergence of the error on the equilibrium shape of the
+# droplet with resolution. The diameter is given in number of grid
+# points.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{convergence.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{kconvergence}Convergence of the relative error on the
+# equilibrium curvature value with resolution. The diameter is given
+# in number of grid points.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{kconvergence.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: St\'ephane Popinet
+# Command: sh spurious.sh spurious.gfs 1e-11
+# Version: 1.1.2
+# Required files: spurious.sh convergence.ref kconvergence.ref
+# Generated files: laplace.eps curvature.eps convergence.eps kconvergence.eps
+#
+
+Define CIRCLE (ellipse (-0.5,0.5,0.4,0.4))
+Define MU sqrt(0.8/LAPLACE)
+
+1 0 GfsSimulation GfsBox GfsGEdge {} {
+  Time { end = TMAX }
+  Refine LEVEL
+  RefineSurface {return 10;} CIRCLE
+
+  ApproxProjectionParams { tolerance = 1e-6 }
+  ProjectionParams { tolerance = 1e-6 }
+  AdvectionParams { scheme = none }
+
+  VariableTracerVOF T
+  VariableCurvature K T
+  SourceTension T 1 K
+  SourceDiffusion U MU
+  SourceDiffusion V MU
+
+  InitFraction T CIRCLE
+  Init {} { Tref = T }
+
+  AdaptGradient { istep = 1 } { cmax = 1e-6 maxlevel = LEVEL } T
+  EventStop { istep = 10 } T DT
+
+  OutputSimulation { start = end } stdout { depth = LEVEL }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $9*sqrt(0.8) }' > La-LAPLACE-LEVEL
+  } { v = Velocity }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9 }' > E-LAPLACE-LEVEL
+  } { v = (Tref - T) }
+  OutputScalarStats { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9, $11 }' > K-LAPLACE-LEVEL
+  } { v = (K - 2.50771) }
+  OutputScalarNorm { istep = 1 } {
+    awk '{ print MU*$3/(0.8*0.8), $5, $7, $9 }' > EK-LAPLACE-LEVEL
+  } { v = (T > 0 && T < 1 ? K - 2.5 : 0) }
+}
+GfsBox {
+  top = Boundary
+  left = Boundary
+}
diff --git a/test/spurious/spurious.sh b/test/spurious/spurious.sh
new file mode 100644
index 0000000..aa16417
--- /dev/null
+++ b/test/spurious/spurious.sh
@@ -0,0 +1,83 @@
+if ! $donotrun; then
+    for La in 120 1200 12000; do
+	tmax=`echo $La | awk '{print 0.8*0.8/sqrt(0.8/$1)}'`
+	if sed "s/end = TMAX/iend = 1/g" < $1 | gerris2D -DLEVEL=5 -DLAPLACE=$La -DDT=0 - |\
+           sed "s/iend = 1/end = $tmax/" | gerris2D - > /dev/null; then :
+	else
+	    exit 1
+	fi
+    done
+
+    La=12000
+    for level in 3 4 6 7; do
+	tmax=`echo $La | awk '{print 0.8*0.8/sqrt(0.8/$1)}'`
+	if sed "s/end = TMAX/iend = 1/g" < $1 | gerris2D -DLEVEL=$level -DLAPLACE=$La -DDT=1e-9 - |\
+           sed "s/iend = 1/end = $tmax/" | gerris2D - > sim-$level; then : 
+	else
+	    exit 1
+	fi
+    done
+fi
+
+rm -f convergence kconvergence
+La=12000
+for level in 3 4 5 6 7; do
+    if awk -v level=$level < E-$La-$level '{
+             max2 = $3
+             maxi = $4
+           }END{print 0.8*2**level, max2, maxi}' >> convergence; then : 
+    else
+	exit 1
+    fi
+    if awk -v level=$level < EK-$La-$level '{
+             max2 = $3
+             maxi = $4
+           }END{print 0.8*2**level, max2/2.5, maxi/2.5}' >> kconvergence; then : 
+    else
+	exit 1
+    fi
+done
+
+if cat <<EOF | gnuplot ; then :
+    set term postscript eps color lw 3 solid 20
+    set output 'laplace.eps'
+    set xlabel 'Tau'
+    set ylabel 'U(D/sigma)^1/2'
+    set logscale y
+    plot 'La-120-5' w l t "La=120", 'La-1200-5' w l t "La=1200", 'La-12000-5' w l t "La=12000"
+    set output 'curvature.eps'
+    set ylabel 'Curvature standard deviation'
+    plot [][1e-12:]'K-120-5' u 1:4 w l t "La=120", 'K-1200-5' u 1:4 w l t "La=1200", 'K-12000-5' u 1:4 w l t "La=12000"
+    set output 'convergence.eps'
+    set xlabel 'D'
+    set ylabel 'Shape error'
+    set logscale x
+    set xtics 2
+    plot [5:120]'convergence' u 1:2 w lp t "RMS" ps 3, 'convergence' u 1:3 w lp t "Max" ps 3, 0.2/(x*x) t "Second order"
+    set output 'kconvergence.eps'
+    set ylabel 'Relative curvature error'
+    set logscale x
+    plot [5:120]'kconvergence' u 1:3 w lp t "" ps 3, 0.6/(x*x) t "Second order"
+EOF
+else
+    exit 1
+fi
+
+for f in La-120-5 La-1200-5 La-12000-5; do
+    if awk -v tolerance=$2 '{ last = $2; }END{if (last > tolerance) exit (1);}' < $f; then :
+    else
+	exit 1
+    fi
+done
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('convergence',1,3) - Curve('convergence.ref',1,3)).max() > 1e-6:
+    exit(1)
+if (Curve('kconvergence',1,3) - Curve('kconvergence.ref',1,3)).max() > 1e-6:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/strouhal/moving.ref b/test/strouhal/moving.ref
new file mode 100644
index 0000000..4e5fd62
--- /dev/null
+++ b/test/strouhal/moving.ref
@@ -0,0 +1,8 @@
+#Re St(high resolution) St(low resolution)
+200    0.207    0.197 
+250    0.214    0.207
+300    0.219    0.214
+350    0.224    0.221
+400    0.226    x
+450    0.229    0.230
+500    0.232    0.234
\ No newline at end of file
diff --git a/test/strouhal/static.ref b/test/strouhal/static.ref
new file mode 100644
index 0000000..e1521f2
--- /dev/null
+++ b/test/strouhal/static.ref
@@ -0,0 +1,8 @@
+#Re St(high resolution) St(low resolution)
+200   0.209    0.195
+250   0.216    0.205
+300   0.221    0.212
+350   0.224    0.218
+400   0.228    0.223
+450   0.231    0.227
+500   0.233    0.231
\ No newline at end of file
diff --git a/test/strouhal/strouhal.gfs b/test/strouhal/strouhal.gfs
new file mode 100644
index 0000000..daeea08
--- /dev/null
+++ b/test/strouhal/strouhal.gfs
@@ -0,0 +1,80 @@
+# Title: B\'enard--von K\'arm\'an vortex street behind a cylinder translating in a fluid at rest
+#
+# Description:
+#
+# An example of 2D viscous flow around a simple solid boundary. A solid
+# cylinder is impulsively started at the right of a channel bounded by
+# solid walls with a slip boundary condition.
+# 
+# Adaptive refinement is used based on the vorticity.
+#
+# After an initial growth phase, a classical B\'enard--von K\'arman
+# vortex street is formed.
+#
+# \begin{figure}[htbp]
+# \caption{\label{vorticity} Vorticity field.}
+# \begin{center}
+# \includegraphics[width=\hsize]{vort.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{Forces} Evolution of the drag and lift coefficients
+# for a Reynolds number of 400.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{forces.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{figure}[htbp]
+# \caption{\label{Strouhal} Strouhal number versus Reynolds
+# number. Comparison between static (reference) and moving problem.}
+# \begin{center}
+# \includegraphics[width=0.8\hsize]{strouhal.eps}
+# \end{center}
+# \end{figure}
+#
+# Author: S\'ebastien Delaux
+# Command: sh strouhal.sh
+# Version: 090512
+# Required files: strouhal.sh strouhal.gfv strouhal.ref moving.ref static.ref
+# Generated files: strouhal.eps vort.eps forces.eps
+#
+1 0 GfsSimulationMoving GfsBox GfsGEdge {} {
+  Time { end = 0.8 }
+  Refine {
+      if (fabs(y) < 0.02 && x > 0.38 && x < 0.42)
+	  return 11;
+      if (fabs(y) < 0.35 && x > 0.3 && x < 0.5)
+	  return 8;
+      return 5;
+  }
+
+  SolidMoving { istep = 1 } cylinder.gts { tx = 0.4 scale = 0.025 } { level = 11 }
+
+  # Set the boundary condition on the solid object.
+  # The velocity is imposed
+  SurfaceBc U Dirichlet -1.
+
+  # Adapt the mesh using the vorticity criterion at every timestep
+  AdaptVorticity { istep = 1 } { maxlevel = (x > 0.5 - t ? 9 : 10) cmax = 1e-2 }
+
+  SourceViscosity 3.125e-5 { beta = 1}
+
+  OutputSimulation { start = end } end.gfs 
+  OutputSolidForce { istep = 1 } forces.dat
+
+  EventScript { start = end } {
+      cat <<EOF | gnuplot 2>&1 | awk '{if ($1 == "400") print $0;}'
+           f(x)= a*cos(b*(x+c))
+           a = 0.00525
+           b = 110.49
+           c = 0.611
+           fit [0.5:] f(x) 'forces.dat' u 1:6 via a,b,c
+           print "400 ", b/(2*pi)*0.0125       
+EOF
+  }
+}
+GfsBox {
+    right = BoundaryOutflow 
+}
diff --git a/test/strouhal/strouhal.gfv b/test/strouhal/strouhal.gfv
new file mode 100644
index 0000000..2e05cfa
--- /dev/null
+++ b/test/strouhal/strouhal.gfv
@@ -0,0 +1,26 @@
+# GfsView 2D
+View {
+  tx = 0.297313 ty = 0.00131029
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 1.73964
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Linear {
+  r = 1 g = 1 b = 1
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = 0
+} Vorticity {
+  amin = 0 min = -300
+  amax = 0 max = 300
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+}
diff --git a/test/strouhal/strouhal.ref b/test/strouhal/strouhal.ref
new file mode 100644
index 0000000..4e6c22b
--- /dev/null
+++ b/test/strouhal/strouhal.ref
@@ -0,0 +1 @@
+400  0.228
\ No newline at end of file
diff --git a/test/strouhal/strouhal.sh b/test/strouhal/strouhal.sh
new file mode 100644
index 0000000..a1b8a15
--- /dev/null
+++ b/test/strouhal/strouhal.sh
@@ -0,0 +1,57 @@
+if ! $donotrun; then 
+    shapes ellipse > cylinder.gts
+    if gerris2D strouhal.gfs > strouhal.res; then :
+    else
+	exit 1
+    fi
+fi
+
+if echo "Save stdout { width = 800 height = 200 }" | \
+    gfsview-batch2D end.gfs strouhal.gfv | \
+    convert -colors 256 ppm:- vort.eps; then :
+else
+    exit 1
+fi
+
+if cat <<EOF | gnuplot ;then :
+   set term pos enhanced eps solid color lw 2
+   set out 'forces.eps'
+   set xl "Time"
+   set yl "Cd/Cl"
+   set yr [-1.25:2.1]
+   set xr [0:112]
+   plot 'forces.dat' u (\$1/0.00625):((\$2+\$5)/0.00625) w l t 'Gerris Moving - Cd',\
+        'forces.dat' u (\$1/0.00625):((\$3+\$6)/0.00625) w l t 'Gerris Moving - Cl'
+
+EOF
+else
+   exit 1
+fi
+
+if cat <<EOF | gnuplot ;then :
+   set term pos enhanced eps solid color lw 2
+   set out 'strouhal.eps'
+   set xl "Reynolds number"
+   set yl "St"
+   set yr [0.19:0.24]
+   set xr [180:520]
+   set key bottom
+   plot 'static.ref' u 1:3 w lp t "Gerris Static Low Resolution",\
+        'moving.ref' u 1:3 pt 5 t "Gerris Moving Low Resolution",\
+        'static.ref' u 1:2 w lp t "Gerris Static High Resolution",\
+        'moving.ref' u 1:2 w lp t "Gerris Moving High Resolution",\
+        'strouhal.res' pt 5 lc 2 t ""
+EOF
+else
+   exit 1
+fi
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if (Curve('strouhal.res',1,2) - Curve('strouhal.ref',1,2)).max() > 0.01 :
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/test/template.tex b/test/template.tex
new file mode 100644
index 0000000..db4c5ee
--- /dev/null
+++ b/test/template.tex
@@ -0,0 +1,120 @@
+\documentclass[a4paper]{article}
+\usepackage{hevea}
+\usepackage[usenames]{color}
+\usepackage{graphicx}
+
+\oddsidemargin=4mm
+\evensidemargin=-1mm
+\topmargin=-7mm
+\textwidth=15.42cm
+\textheight=23.2cm
+
+\newcommand{\htmladdnormallinkfoot}[2]{\footahref{#2}{#1}}
+\newcommand{\htmladdnormallink}[2]{\ahref{#2}{#1}}
+\renewcommand{\cuttingunit}{subsection}
+
+\title{Gerris test suite}
+
+\begin{document}
+
+\mbox{}\vspace{1cm}
+\begin{center}
+{\Huge Gerris Tests}\\
+\vspace{1cm}
+\input{summary.tex}
+\vspace{5mm}
+\end{center}
+
+\section{Introduction}
+
+This document is automatically generated from the results obtained
+when running the Gerris test suite. The test suite is run daily on the
+development branch of the version-controlled source code. 
+
+Note that the stable branch (from which snapshot versions and packages
+are generated) is only updated when all of the tests succeed i.e. the
+status of the test cases below reflects the state of the development
+branch only.
+
+\section{Poisson}
+
+\input{poisson/poisson.tex}
+\input{poisson/circle/circle.tex}
+\input{circle/circle.tex}
+\input{circle/star/star.tex}
+\input{circle/refined/refined.tex}
+\input{circle/thin/thin.tex}
+\input{dumbell/dumbell.tex}
+
+\section{Advection}
+
+\input{advection/advection.tex}
+\input{shear/shear.tex}
+\input{shear/curvature/curvature.tex}
+
+\section{Euler}
+
+\input{reynolds/reynolds.tex}
+\input{reynolds/box/box.tex}
+\input{periodic/periodic.tex}
+\input{merging/merging.tex}
+
+\section{Axisymmetric}
+\input{axi/axi.tex}
+\input{axi/viscous/viscous.tex}
+\input{axiadvection/axiadvection.tex}
+\input{axiadvection/solid/solid.tex}
+
+\section{Navier-Stokes}
+
+\input{lid/lid.tex}
+\input{lid/explicit/explicit.tex}
+\input{poiseuille/poiseuille.tex}
+\input{couette/couette.tex}
+\input{kinetic/kinetic.tex}
+\input{hydrostatic/hydrostatic.tex}
+\input{hydrostatic/quadratic/quadratic.tex}
+
+\section{Solid boundaries}
+
+\input{boundaries/boundaries.tex}
+\input{channel/channel.tex}
+\input{plate/plate.tex}
+
+\section{Moving solid boundaries}
+
+\input{hexagon/hexagon.tex}
+\input{strouhal/strouhal.tex}
+
+\section{Surface tension}
+
+\input{spurious/spurious.tex}
+\input{spurious/axi/axi.tex}
+\input{capwave/capwave.tex}
+\input{capwave/density/density.tex}
+\input{capwave/air-water/air-water.tex}
+\input{capwave/gravity/gravity.tex}
+\input{oscillation/oscillation.tex}
+
+\section{Shallow-water}
+
+\input{geo/geo.tex}
+\input{geo/beta/beta.tex}
+\input{waves/waves.tex}
+\input{waves/adaptive/adaptive.tex}
+\input{nz/nz.tex}
+
+\section{Saint-Venant}
+
+\input{parabola/parabola.tex}
+
+\section{General Orthogonal Coordinates}
+
+\input{lonlat/lonlat.tex}
+\input{lonlat/coriolis/coriolis.tex}
+\input{cosine/cosine.tex}
+
+\bibliographystyle{plain}
+\bibliography{tests}
+
+\end{document}
diff --git a/test/test.py b/test/test.py
new file mode 100644
index 0000000..516ff7c
--- /dev/null
+++ b/test/test.py
@@ -0,0 +1,72 @@
+import sys
+import commands
+import os
+import os.path
+sys.path.append("../doc/examples")
+import gfs2tex
+from datetime import *
+
+env = "export PYTHONPATH=$PYTHONPATH:" + os.getcwd() + " && export donotrun=false &&"
+system = commands.getoutput('uname -o -n -m')
+path = commands.getoutput('which gerris2D')
+version = commands.getoutput("""gerris2D -V 2>&1 | head -1 | cut -d' ' -f6-""")
+starttime = datetime.now()
+
+n = 0
+failed = 0
+for start in sys.argv[1:]:
+    for root, dirs, files in os.walk(start,topdown=True):
+        if not ".xvpics" in root:
+            test = gfs2tex.Example(root)
+            status,msg = test.run(env)
+            if status != None:
+                print "FAIL:",root
+                if len(msg) > 0:
+                    print " ".join(msg)
+                print >>open(test.path + "/status",'w'), "{\color{Red}FAIL}:"
+                failed += 1
+            else:
+                print "PASS:",root
+                print >>open(test.path + "/status",'w'), "{\color{OliveGreen}PASS}:"
+            n += 1
+
+endtime = datetime.now()
+e = endtime - starttime
+s = e.seconds
+h = int(s/3600)
+s -= h*3600
+m = int(s/60)
+s -= m*60
+
+summary = open('summary.tex','w')
+print >>summary, r'\begin{tabular}{ll}'
+print >>summary, r'{\bf Version} &', version, r'\\'
+print >>summary, r'{\bf Path} &', path, r'\\'
+print >>summary, r'{\bf System} &', system, r'\\'
+print >>summary, r'{\bf Start} &', starttime.strftime('%a %d %b %H:%M:%S'), r'\\'
+print >>summary, r'{\bf Finish} &', endtime.strftime('%a %d %b %H:%M:%S'), r'\\'
+elapsed = ""
+if e.days > 0:
+    elapsed += '%02d:' % e.days
+if h > 0:
+    elapsed += '%02d:' % h
+elapsed += '%02d:%02d' % (m,s)
+print >>summary, r'{\bf Elapsed} &', elapsed, r'\\'
+print >>summary, r'{\bf Status} &',
+if failed:
+    print >>summary, r'{\color{Red}FAIL (' + repr(failed) + '/' + repr(n) +')}'
+else:
+    print >>summary, r'{\color{OliveGreen}PASS (' + repr(n) + ')}'
+print >>summary, r'\end{tabular}'
+
+if failed:
+    msg = repr(failed) + " of " + repr(n) + " tests failed"
+else:
+    msg = "All " + repr(n) + " tests passed"
+
+print len(msg)*"="
+print msg
+print len(msg)*"="
+
+if failed:
+    sys.exit(1)
diff --git a/test/tests.bib b/test/tests.bib
new file mode 100644
index 0000000..f5bd5eb
--- /dev/null
+++ b/test/tests.bib
@@ -0,0 +1,321 @@
+ at Article{almgren97,
+  author =	 {A. S. Almgren and J. B. Bell and P. Colella and
+                  T. Marthaler},
+  title =	 {A Cartesian Grid Projection Method for the
+                  Incompressible Euler Equations in Complex
+                  Geometries},
+  journal =	 {SIAM J. Sci. Comp.},
+  year =	 1997,
+  volume =	 18,
+  number =	 5,
+  pages =	 {1289-1309},
+  url =
+                  {http://seesar.lbl.gov/ccse/Publications/almgren/abcm.sisc/paper.ps.gz},
+  local_url =	 {almgren.ps.gz}
+}
+
+ at Article{almgren98,
+  author =	 {A. S. Almgren and J. B. Bell and P. Colella and
+                  L. H. Howell and M. L. Welcome},
+  title =	 {A Conservative Adaptive Projection Method for the
+                  Variable Density Incompressible Navier-Stokes
+                  Equations},
+  journal =	 {J. Comput. Phys.},
+  year =	 1998,
+  volume =	 142,
+  pages =	 {1-46},
+  url =
+                  {http://seesar.lbl.gov/ccse/Publications/almgren/abchw96/paper.ps.gz},
+  local_url =	 {almgren1.ps.gz}
+}
+
+ at Book{bird87,
+  author =	 {R. B. Bird and R. C. Armstrong and O. Hassager},
+  title =	 {Dynamics of polymeric liquids},
+  publisher =	 {Wiley-Interscience},
+  year =	 1987,
+  edition =	 {second edition}
+}
+
+ at article{blanco1995,
+  title =	 {The structure of the axisymmetric high-{R}eynolds
+                  number flow around an ellipsoidal bubble of fixed
+                  shape},
+  author =	 {Blanco, A. and Magnaudet, J.},
+  journal =	 {Physics of Fluids},
+  volume =	 7,
+  pages =	 1265,
+  year =	 1995,
+  publisher =	 {AIP}
+}
+
+ at PhdThesis{dupont,
+  author =	 {F. Dupont},
+  title =	 {Comparison of numerical methods for modelling ocean
+                  circulation in basins with irregular coasts},
+  school =	 {McGill University},
+  year =	 2001,
+  address =	 {Montreal}
+}
+
+ at article{fadlun2000,
+  title =	 {Combined immersed-boundary finite-difference methods
+                  for three-dimensional complex flow simulations},
+  author =	 {Fadlun, EA and Verzicco, R. and Orlandi, P. and
+                  Mohd-Yusof, J.},
+  journal =	 {Journal of Computational Physics},
+  volume =	 161,
+  number =	 1,
+  pages =	 {35--60},
+  year =	 2000
+}
+
+ at Article{fornberg1988,
+  author =	 {B. Fornberg},
+  title =	 {Steady viscous flow past a sphere at high {R}eynolds
+                  number},
+  journal =	 {J. Fluid Mech.},
+  year =	 1988,
+  volume =	 190,
+  pages =	 471
+}
+
+ at article{gerlach2006,
+  author =	 {D. Gerlach and G. Tomar and G. Biswas and F. Durst},
+  title =	 {Comparison of surface tension methods for surface
+                  tension dominant two-phase flows},
+  journal =	 {Int. J.  Heat Mass Transfer},
+  year =	 2006,
+  pages =	 {740-754},
+  volume =	 49
+}
+
+ at Article{ghia82,
+  author =	 {U. Ghia, K.N. Ghia, C.T. Shin},
+  title =	 {High-{R}e solution for incompressible flow using the
+                  {N}avier-{S}tokes equations and the multigrid
+                  method},
+  journal =	 {J. Comput. Phys.},
+  year =	 1982,
+  volume =	 48,
+  pages =	 {387-411}
+}
+
+ at Article{gueyffier98,
+  author =	 {D. Gueyffier and A. Nadim and J. Li and
+                  R. Scardovelli and S. Zaleski},
+  title =	 {Volume of fluid interface tracking with smoothed
+                  surface stress methods for three-dimensional flows},
+  journal =	 {J. Comp. Phys.},
+  year =	 1998,
+  volume =	 152,
+  pages =	 {423-456}
+}
+
+ at Book{lamb,
+  author =	 {H. Lamb},
+  title =	 {Hydrodynamics},
+  publisher =	 {Dover},
+  year =	 1932
+}
+
+ at Article{leroux98,
+  author =	 {D. Y. Leroux and C. A. Lin},
+  title =	 {Finite elements for shallow-water equations ocean
+                  models},
+  journal =	 {Monthly Weather Review},
+  year =	 1998,
+  volume =	 126,
+  pages =	 {1931-1951}
+}
+
+ at Article{liang2008,
+  title =	 {Adaptive quadtree simulation of shallow flows with
+                  wet--dry fronts over complex topography},
+  author =	 {Q. Liang and A.G.L. Borthwick},
+  journal =	 {Computers and Fluids},
+  year =	 2008,
+  publisher =	 {Elsevier}
+}
+
+ at Article{lynch87,
+  author =	 {D. R. Lynch and F. E. Werner},
+  title =	 {3-{D} hydrodynamics on finite elements. {P}art I:
+                  linearized harmonic model},
+  journal =	 {Int. J. for Num. Methods in Fluids},
+  year =	 1987,
+  number =	 7,
+  pages =	 {871-909}
+}
+
+ at article{masliyah1970,
+  title =	 {Numerical study of steady flow past spheroids},
+  author =	 {Masliyah, J.H. and Epstein, N.},
+  journal =	 {Journal of Fluid Mechanics},
+  volume =	 44,
+  number =	 03,
+  pages =	 {493--512},
+  year =	 1970,
+  publisher =	 {Cambridge Univ Press}
+}
+
+ at Article{minion96,
+  author =	 {M. L. Minion},
+  title =	 {A Projection Method for Locally Refined Grids},
+  journal =	 {J. Comput. Phys.},
+  volume =	 127,
+  pages =	 {158-177},
+  year =	 1996,
+  url =		 {http://citeseer.nj.nec.com/minion96projection.html},
+  local_url =	 {minion96.ps.gz}
+}
+
+ at Article{peraire86,
+  author =	 {J. Peraire and O. C. Zienkiewicz and K. Morgan},
+  title =	 {Shallow water problems: a general explicit
+                  formulation},
+  journal =	 {Int. J. for Num. Methods in Eng.},
+  year =	 1986,
+  volume =	 22,
+  pages =	 {547-574}
+}
+
+ at Article{popinet2003,
+  author =	 {S. Popinet},
+  title =	 {Gerris: a tree-based adaptive solver for the
+                  incompressible Euler equations in complex
+                  geometries},
+  journal =	 {J. Comput. Phys.},
+  year =	 2003,
+  volume =	 190,
+  number =	 2,
+  pages =	 {572-600},
+  url =		 {http://gfs.sf.net/gerris.pdf}
+}
+
+ at Article{popinet99,
+  author =	 {S. Popinet and S. Zaleski},
+  title =	 {A front tracking algorithm for the accurate
+                  representation of surface tension},
+  journal =	 {Int. J. Numer. Meth. Fluids},
+  volume =	 30,
+  pages =	 {775-793},
+  year =	 1999
+}
+
+ at Article{prosperetti81,
+  author =	 {A. Prosperetti},
+  title =	 {Motion of two superposed viscous fluids},
+  journal =	 {Phys. Fluids},
+  year =	 1981,
+  volume =	 24,
+  pages =	 {1217-1223}
+}
+
+ at TechReport{rider95,
+  author =	 {W. J. Rider},
+  title =	 {Approximate projection methods for incompressible
+                  flows: Implementation, variants and robustness},
+  institution =	 {Los Alamos National Laboratory},
+  year =	 1995,
+  number =	 {LA-UR-2000},
+  local_url =	 {rider95.ps.gz},
+  url =
+                  {http://www-xdiv.lanl.gov/XHM/personnel/wjr/Web_papers/proj/proj.ps.Z},
+  pages =	 {81-85}
+}
+
+ at Article{rossmanith2004,
+  author =	 {J. A, Rossmanith and D. S. Bale and R. J. LeVeque},
+  title =	 {A wave propagation algorithm for hyperbolic systems
+                  on curved manifolds},
+  journal =	 {Journal of Computational Physics},
+  year =	 2004,
+  volume =	 199,
+  pages =	 {631-662}
+}
+
+ at article{rossmanith2006,
+  title =	 {A wave propagation method for hyperbolic systems on
+                  the sphere},
+  author =	 {Rossmanith, J.A.},
+  journal =	 {Journal of Computational Physics},
+  volume =	 213,
+  number =	 2,
+  pages =	 {629--658},
+  year =	 2006,
+  publisher =	 {Elsevier}
+}
+
+ at article{rudman97,
+  title =	 {Volume-tracking methods for interfacial flow
+                  calculations},
+  author =	 {Rudman, M.},
+  journal =	 {International Journal for Numerical Methods in
+                  Fluids},
+  volume =	 24,
+  number =	 7,
+  pages =	 {671--691},
+  year =	 1997
+}
+
+ at TechReport{rutgers-waves,
+  author =	 {E. Curchitser},
+  title =	 {Waves in a circular basin},
+  institution =	 {Rutgers University},
+  year =	 2005,
+  url =
+                  {http://marine.rutgers.edu/po/index.php?model=test-problems&title=circle}
+}
+
+ at Article{sampson2006,
+  title =	 {Moving boundary shallow water flow above parabolic
+                  bottom topography},
+  author =	 {J. Sampson and A. Easton and M. Singh},
+  journal =	 {ANZIAM J},
+  volume =	 47,
+  year =	 2006
+}
+
+ at Article{torres00,
+  author =	 {D. J. Torres and J. U. Brackbill},
+  title =	 {The Point-Set method: front-tracking without
+                  connectivity},
+  journal =	 {J. Comput. Phys.},
+  year =	 2000,
+  volume =	 165,
+  pages =	 {620-644}
+}
+
+ at Article{vola2004,
+  author =	 {D. Vola and F. Babik and J.-C Latch\'e},
+  title =	 {On a numerical strategy to compute gravity currents
+                  of non-Newtonian fluids},
+  journal =	 {J. Comput. Phys.},
+  year =	 2004,
+  volume =	 201,
+  number =	 2,
+  pages =	 {397-420}
+}
+
+ at Article{williamson92,
+  author =	 {{Williamson}, D.~L. and {Drake}, J.~B. and {Hack},
+                  J.~J. and {Jakob}, R. and {Swarztrauber}, P.~N.},
+  title =	 {A standard test set for numerical approximations to
+                  the shallow water equations in spherical geometry},
+  journal =	 {Journal of Computational Physics},
+  year =	 1992,
+  volume =	 102,
+  pages =	 {211-224},
+  doi =		 {10.1016/S0021-9991(05)80016-6}
+}
+
+ at Article{zhang2007,
+  author =	 {N. Zhang and Z.C. Zheng},
+  title =	 {An improved direct-forcing immersed-boundary method
+                  for finite difference applications},
+  journal =	 {Journal of Computational Physics},
+  year =	 2007,
+  volume =	 221,
+  pages =	 {250-268}
+}
diff --git a/test/waves/adaptive/adaptive.gfs b/test/waves/adaptive/adaptive.gfs
new file mode 100644
index 0000000..f09873d
--- /dev/null
+++ b/test/waves/adaptive/adaptive.gfs
@@ -0,0 +1,624 @@
+# Title: Coastally-trapped waves with adaptive refinement
+#
+# Description:
+#
+# Same test case as before but with adaptive refinement (using the
+# vorticity criterion).
+#
+# Figure \ref{solution} illustrates the solution obtained after three
+# wave periods.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Surface-height after a rotation of 3 wave
+# periods. The maximum resolution is 9.375 km (dark red), the minimum
+# resolution is 150 km (dark blue).}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{table}[htbp]
+# \caption{\label{correlation}Maximum correlation and phase error as functions of resolution.}
+# \begin{center}
+# \input{correlation.tex}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh ../waves.sh adaptive.gfs
+# Version: 1.0.0
+# Required files: solution.gfv correlation.ref
+# Generated files: correlation correlation.tex solution.eps
+#
+1 0 GfsOcean GfsBox GfsGEdge {} {
+  Time { end = 37.80501984 dtmax = 0.1 }
+  PhysicalParams { g = 5.87060327757e-3 }
+  Global {
+    #include <gsl/gsl_sf_bessel.h>
+    @link -lgsl -lgslcblas
+    
+    #define Ik(k,r,D) (gsl_sf_bessel_Inu ((k) - 1., (r)/(D))/(D)\
+                          - (k)/(r)*gsl_sf_bessel_Inu ((k), (r)/(D)))
+
+    static double D = 8.83906519983e-2;
+    static double k = 3.;
+    static double sigma = 0.4986;
+    static double a = 1./2555510.;
+    
+    static double pwave (double x, double y, double angle) {
+      double theta = atan2 (y, x) + angle*M_PI/180.;
+      double r = sqrt (x*x + y*y);
+      return a*cos (k*theta)*gsl_sf_bessel_Inu (k, r/D);
+    }
+
+    static double ur (double theta, double r) {
+      return -a*D*D/5.87060327757e-3*sin (k*theta)*(sigma*Ik (k, r, D) - 
+          k/r*gsl_sf_bessel_Inu (k, r/D));
+    }
+
+    static double vt (double theta, double r) {
+      return a*D*D/5.87060327757e-3*cos (k*theta)*(Ik (k, r, D) - 
+       	  k*sigma/r*gsl_sf_bessel_Inu (k, r/D));
+    }
+
+    static double uwave (double x, double y) {
+      double theta = atan2 (y, x);
+      double r = sqrt (x*x + y*y);
+      return ur (theta, r)*cos (theta) - vt (theta, r)*sin (theta);
+    }
+
+    static double vwave (double x, double y) {
+      double theta = atan2 (y, x);
+      double r = sqrt (x*x + y*y);
+      return ur (theta, r)*sin (theta) + vt (theta, r)*cos (theta);
+    }
+  }
+  Init {} {
+    P = pwave(cx, cy, 0)
+    U = uwave(x, y)
+    V = vwave(x, y)
+    H = 1
+  }
+  Refine LEVEL
+  AdaptVorticity { istep = 1 } { cmax = 5e-2 maxlevel = LEVEL }
+  Solid (- ellipse (0, 0, 0.25, 0.25)) { scale = 1.999 }
+  AdvectionParams { scheme = none }
+  ApproxProjectionParams { tolerance = 1e-9 weighted = 0 }
+  SourceCoriolis {} 1.
+  EventFilter { istep = 1 } U 4
+  EventFilter { istep = 1 } V 4
+  EventScript { start = end } { echo -n "-30 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -30)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-29 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -29)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-28 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -28)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-27 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -27)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-26 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -26)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-25 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -25)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-24 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -24)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-23 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -23)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-22 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -22)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-21 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -21)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-20 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -20)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-19 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -19)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-18 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -18)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-17 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -17)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-16 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -16)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-15 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -15)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-14 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -14)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-13 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -13)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-12 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -12)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-11 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -11)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-10 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -10)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "10 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 10)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "11 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 11)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "12 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 12)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "13 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 13)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "14 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 14)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "15 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 15)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "16 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 16)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "17 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 17)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "18 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 18)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "19 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 19)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "20 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 20)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "21 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 21)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "22 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 22)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "23 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 23)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "24 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 24)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "25 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 25)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "26 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 26)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "27 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 27)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "28 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 28)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "29 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 29)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "30 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 30)
+    unbiased = 1
+  }
+  OutputSimulation { start = end } sim-LEVEL
+}
+GfsBox {
+  front = Boundary
+}
diff --git a/test/waves/adaptive/correlation.ref b/test/waves/adaptive/correlation.ref
new file mode 100644
index 0000000..c049183
--- /dev/null
+++ b/test/waves/adaptive/correlation.ref
@@ -0,0 +1,3 @@
+5		2.6			0.8648
+6		0.6			0.9707
+7		0.4			0.991
diff --git a/test/waves/adaptive/solution.gfv b/test/waves/adaptive/solution.gfv
new file mode 100644
index 0000000..7f351f5
--- /dev/null
+++ b/test/waves/adaptive/solution.gfv
@@ -0,0 +1,40 @@
+# GfsView 3D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = -0.5
+} Level {
+  amin = 1
+  amax = 1
+  cmap = Jet
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = -0.5
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 16
+}
diff --git a/test/waves/correlation.ref b/test/waves/correlation.ref
new file mode 100644
index 0000000..0484393
--- /dev/null
+++ b/test/waves/correlation.ref
@@ -0,0 +1,3 @@
+5		2.7			0.8645
+6		0.6			0.9717
+7		0.2			0.9923
diff --git a/test/waves/solution.gfv b/test/waves/solution.gfv
new file mode 100644
index 0000000..2e8213b
--- /dev/null
+++ b/test/waves/solution.gfv
@@ -0,0 +1,40 @@
+# GfsView 3D
+View {
+  tx = 0 ty = 0
+  sx = 1 sy = 1 sz = 1
+  q0 = 0 q1 = 0 q2 = 0 q3 = 1
+  fov = 30
+  r = 0.3 g = 0.4 b = 0.6
+  res = 1
+  lc = 0.001
+  reactivity = 0.1
+}
+Squares {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = -0.5
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+}
+Isoline {
+  r = 0 g = 0 b = 0
+  shading = Constant
+  maxlevel = -1
+} {
+  n.x = 0 n.y = 0 n.z = 1
+  pos = -0.5
+} P {
+  amin = 1
+  amax = 1
+  cmap = Jet
+} 0 {
+  reversed = 0
+  use_scalar = 1
+} {
+  n = 16
+}
diff --git a/test/waves/waves.gfs b/test/waves/waves.gfs
new file mode 100644
index 0000000..5ff29dc
--- /dev/null
+++ b/test/waves/waves.gfs
@@ -0,0 +1,635 @@
+# Title: Coastally-trapped waves
+#
+# Description:
+#
+# A simulation is initialised with an exact solution found by Lamb
+# \cite{lamb} for inertia-gravity waves in a circular, flat-bottomed
+# basin on an $f$-plane.
+#
+# The waves should rotate unchanged around the basin. This is a good
+# test of the shallow-water solver with Coriolis terms and non-trivial
+# coastlines.
+#
+# Figure \ref{solution} illustrates the solution obtained after three
+# wave periods.
+#
+# Following \cite{rutgers-waves}, Table \ref{correlation} presents the
+# phase error and the maximum correlation between the computed
+# solution and the exact solution. Note that these results are not
+# directly comparable to \cite{rutgers-waves}, because the timestep
+# used is much larger. The time-explicit codes tested in
+# \cite{rutgers-waves} have stronger stability requirements than
+# Gerris.
+#
+# \begin{figure}[htbp]
+# \caption{\label{solution}Surface-height after a rotation of 3 wave periods for a
+# resolution of 9.375 km.}
+# \begin{center}
+# \includegraphics[width=0.6\hsize]{solution.eps}
+# \end{center}
+# \end{figure}
+#
+# \begin{table}[htbp]
+# \caption{\label{correlation}Maximum correlation and phase error as functions of resolution.}
+# \begin{center}
+# \input{correlation.tex}
+# \end{center}
+# \end{table}
+#
+# Author: St\'ephane Popinet
+# Command: sh waves.sh waves.gfs
+# Version: 1.0.0
+# Required files: waves.sh solution.gfv correlation.ref
+# Generated files: correlation correlation.tex solution.eps
+#
+1 0 GfsOcean GfsBox GfsGEdge {} {
+  Time { end = 37.80501984 dtmax = 0.1 }
+  PhysicalParams { g = 5.87060327757e-3 }
+  Global {
+    #include <gsl/gsl_sf_bessel.h>
+    @link -lgsl -lgslcblas
+    
+    #define Ik(k,r,D) (gsl_sf_bessel_Inu ((k) - 1., (r)/(D))/(D)\
+                          - (k)/(r)*gsl_sf_bessel_Inu ((k), (r)/(D)))
+
+    static double D = 8.83906519983e-2;
+    static double k = 3.;
+    static double sigma = 0.4986;
+    static double a = 1./2555510.;
+    
+    static double pwave (double x, double y, double angle) {
+      double theta = atan2 (y, x) + angle*M_PI/180.;
+      double r = sqrt (x*x + y*y);
+      return a*cos (k*theta)*gsl_sf_bessel_Inu (k, r/D);
+    }
+
+    static double ur (double theta, double r) {
+      return -a*D*D/5.87060327757e-3*sin (k*theta)*(sigma*Ik (k, r, D) - 
+          k/r*gsl_sf_bessel_Inu (k, r/D));
+    }
+
+    static double vt (double theta, double r) {
+      return a*D*D/5.87060327757e-3*cos (k*theta)*(Ik (k, r, D) - 
+       	  k*sigma/r*gsl_sf_bessel_Inu (k, r/D));
+    }
+
+    static double uwave (double x, double y) {
+      double theta = atan2 (y, x);
+      double r = sqrt (x*x + y*y);
+      return ur (theta, r)*cos (theta) - vt (theta, r)*sin (theta);
+    }
+
+    static double vwave (double x, double y) {
+      double theta = atan2 (y, x);
+      double r = sqrt (x*x + y*y);
+      return ur (theta, r)*sin (theta) + vt (theta, r)*cos (theta);
+    }
+  }
+  Init {} {
+    P = pwave(cx, cy, 0)
+    U = uwave(x, y)
+    V = vwave(x, y)
+    H = 1
+  }
+  Refine LEVEL
+  Solid (- ellipse (0, 0, 0.25, 0.25)) { scale = 1.999 }
+  AdvectionParams { scheme = none }
+  ApproxProjectionParams { tolerance = 1e-9 weighted = 0 }
+  SourceCoriolis {} 1.
+  EventFilter { istep = 1 } U 4
+  EventFilter { istep = 1 } V 4
+  EventScript { start = end } { echo -n "-30 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -30)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-29 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -29)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-28 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -28)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-27 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -27)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-26 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -26)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-25 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -25)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-24 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -24)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-23 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -23)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-22 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -22)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-21 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -21)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-20 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -20)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-19 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -19)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-18 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -18)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-17 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -17)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-16 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -16)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-15 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -15)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-14 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -14)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-13 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -13)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-12 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -12)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-11 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -11)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-10 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -10)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "-1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, -1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "0.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 0.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "1.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 1.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "2.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 2.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "3.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 3.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.1 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.1)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.2 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.2)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.3 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.3)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.4 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.4)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "4.9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 4.9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "5 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 5)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "6 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 6)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "7 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 7)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "8 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 8)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "9 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 9)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "10 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 10)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "11 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 11)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "12 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 12)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "13 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 13)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "14 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 14)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "15 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 15)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "16 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 16)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "17 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 17)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "18 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 18)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "19 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 19)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "20 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 20)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "21 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 21)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "22 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 22)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "23 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 23)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "24 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 24)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "25 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 25)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "26 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 26)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "27 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 27)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "28 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 28)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "29 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 29)
+    unbiased = 1
+  }
+  EventScript { start = end } { echo -n "30 " }
+  OutputCorrelation { start = end } stdout { v = P } {
+    s = pwave(cx, cy, 30)
+    unbiased = 1
+  }
+  OutputSimulation { start = end } sim-LEVEL
+}
+GfsBox {
+  front = Boundary
+}
diff --git a/test/waves/waves.sh b/test/waves/waves.sh
new file mode 100644
index 0000000..0462dee
--- /dev/null
+++ b/test/waves/waves.sh
@@ -0,0 +1,43 @@
+if ! $donotrun; then
+    rm -f correlation res-* sim-*
+    for level in 5 6 7; do
+	if sed "s/LEVEL/$level/g" < $1 | gerris2D3 - | \
+	    awk '{ print $1 " " $5 }' > res-$level && \
+	    awk -v l=$level 'BEGIN { min1 = 0. } {
+         if ($2 > min1) {
+           theta = $1;
+           min1 = $2;
+         }
+       } END {
+           printf ("%d\t\t%g\t\t\t%g\n", l, theta, min1);
+       }' < res-$level >> correlation; then :
+	else
+	    exit 1
+	fi
+    done
+fi
+
+echo "Save solution.eps { format = EPS }" | gfsview-batch2D3 sim-7 solution.gfv
+
+awk 'BEGIN {
+  print "\\begin{tabular}{|c|c|c|}"
+  print "\\hline Level & Maximum $C$ & Angle of max $C$ \\\\ \\hline"
+}{
+  print $1 " & " $3 " & " $2 " \\\\"
+}END {
+  print "\\hline"
+  print "\\end{tabular}"
+}' < correlation > correlation.tex
+
+if cat <<EOF | python ; then :
+from check import *
+from sys import *
+if Curve('correlation',1,3).max() > 10.:
+    exit(1)
+if (Curve('correlation',1,2) - Curve('correlation.ref',1,2)).max() > 0. or\
+   (Curve('correlation.ref',1,3) - Curve('correlation',1,3)).max() > 0.:
+    exit(1)
+EOF
+else
+   exit 1
+fi
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..a28b37a
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,58 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) -DG_LOG_DOMAIN=\"Gfs-tools\"\
+            $(GTS_CFLAGS)
+
+bin_PROGRAMS = \
+	gfs2oogl2D \
+	gfs2oogl2D3 \
+	gfs2oogl3D \
+	streamanime \
+	ppmcombine \
+	gfscompare2D \
+	gfscompare2D3 \
+	gfscompare3D \
+	gfsjoin2D \
+	gfsjoin3D \
+	shapes
+
+bin_SCRIPTS = \
+	darcs2dist \
+	bat2gts \
+	ppm2mpeg \
+	ppm2theora \
+	ppm2video \
+	gfs2gfs \
+	gfsjoin
+
+EXTRA_DIST = $(bin_SCRIPTS)
+
+gfs2oogl2D_SOURCES = gfs2oogl.c
+gfs2oogl2D3_SOURCES = gfs2oogl.c
+gfs2oogl3D_SOURCES = gfs2oogl.c
+gfscompare2D_SOURCES = gfscompare.c
+gfscompare2D3_SOURCES = gfscompare.c
+gfscompare3D_SOURCES = gfscompare.c
+gfsjoin2D_SOURCES = gfsjoin2.c
+gfsjoin3D_SOURCES = gfsjoin2.c
+
+gfs2oogl2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfs2oogl2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gfs2oogl2D_LDADD = $(GFS2D_LIBS)
+gfs2oogl2D3_LDADD = $(GFS2D3_LIBS)
+gfs2oogl3D_LDADD = $(GFS3D_LIBS)
+gfscompare2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfscompare2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gfscompare2D_LDADD = $(GFS2D_LIBS)
+gfscompare2D3_LDADD = $(GFS2D3_LIBS)
+gfscompare3D_LDADD = $(GFS3D_LIBS)
+gfsjoin2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfsjoin2D_LDADD = $(GFS2D_LIBS)
+gfsjoin3D_LDADD = $(GFS3D_LIBS)
+
+ppmcombine_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+ppmcombine_LDADD = $(GFS2D_LIBS)
+
+streamanime_LDADD = $(GFS3D_LIBS)
+
+shapes_LDADD = $(GTS_LIBS)
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..58da2ae
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,818 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = gfs2oogl2D$(EXEEXT) gfs2oogl2D3$(EXEEXT) \
+	gfs2oogl3D$(EXEEXT) streamanime$(EXEEXT) ppmcombine$(EXEEXT) \
+	gfscompare2D$(EXEEXT) gfscompare2D3$(EXEEXT) \
+	gfscompare3D$(EXEEXT) gfsjoin2D$(EXEEXT) gfsjoin3D$(EXEEXT) \
+	shapes$(EXEEXT)
+subdir = tools
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_gfs2oogl2D_OBJECTS = gfs2oogl2D-gfs2oogl.$(OBJEXT)
+gfs2oogl2D_OBJECTS = $(am_gfs2oogl2D_OBJECTS)
+am__DEPENDENCIES_1 =
+gfs2oogl2D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gfs2oogl2D_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gfs2oogl2D_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gfs2oogl2D3_OBJECTS = gfs2oogl2D3-gfs2oogl.$(OBJEXT)
+gfs2oogl2D3_OBJECTS = $(am_gfs2oogl2D3_OBJECTS)
+gfs2oogl2D3_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gfs2oogl2D3_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gfs2oogl2D3_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gfs2oogl3D_OBJECTS = gfs2oogl.$(OBJEXT)
+gfs2oogl3D_OBJECTS = $(am_gfs2oogl3D_OBJECTS)
+gfs2oogl3D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_gfscompare2D_OBJECTS = gfscompare2D-gfscompare.$(OBJEXT)
+gfscompare2D_OBJECTS = $(am_gfscompare2D_OBJECTS)
+gfscompare2D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gfscompare2D_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gfscompare2D_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gfscompare2D3_OBJECTS = gfscompare2D3-gfscompare.$(OBJEXT)
+gfscompare2D3_OBJECTS = $(am_gfscompare2D3_OBJECTS)
+gfscompare2D3_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gfscompare2D3_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gfscompare2D3_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gfscompare3D_OBJECTS = gfscompare.$(OBJEXT)
+gfscompare3D_OBJECTS = $(am_gfscompare3D_OBJECTS)
+gfscompare3D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_gfsjoin2D_OBJECTS = gfsjoin2D-gfsjoin2.$(OBJEXT)
+gfsjoin2D_OBJECTS = $(am_gfsjoin2D_OBJECTS)
+gfsjoin2D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+gfsjoin2D_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(gfsjoin2D_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_gfsjoin3D_OBJECTS = gfsjoin2.$(OBJEXT)
+gfsjoin3D_OBJECTS = $(am_gfsjoin3D_OBJECTS)
+gfsjoin3D_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ppmcombine_SOURCES = ppmcombine.c
+ppmcombine_OBJECTS = ppmcombine-ppmcombine.$(OBJEXT)
+ppmcombine_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ppmcombine_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ppmcombine_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+shapes_SOURCES = shapes.c
+shapes_OBJECTS = shapes.$(OBJEXT)
+shapes_DEPENDENCIES = $(am__DEPENDENCIES_1)
+streamanime_SOURCES = streamanime.c
+streamanime_OBJECTS = streamanime.$(OBJEXT)
+streamanime_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(gfs2oogl2D_SOURCES) $(gfs2oogl2D3_SOURCES) \
+	$(gfs2oogl3D_SOURCES) $(gfscompare2D_SOURCES) \
+	$(gfscompare2D3_SOURCES) $(gfscompare3D_SOURCES) \
+	$(gfsjoin2D_SOURCES) $(gfsjoin3D_SOURCES) ppmcombine.c \
+	shapes.c streamanime.c
+DIST_SOURCES = $(gfs2oogl2D_SOURCES) $(gfs2oogl2D3_SOURCES) \
+	$(gfs2oogl3D_SOURCES) $(gfscompare2D_SOURCES) \
+	$(gfscompare2D3_SOURCES) $(gfscompare3D_SOURCES) \
+	$(gfsjoin2D_SOURCES) $(gfsjoin3D_SOURCES) ppmcombine.c \
+	shapes.c streamanime.c
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GFS2D3_LIBS = @GFS2D3_LIBS@
+GFS2D_LIBS = @GFS2D_LIBS@
+GFS3D_LIBS = @GFS3D_LIBS@
+GFS_COMPILATION_FLAGS = @GFS_COMPILATION_FLAGS@
+GFS_MAJOR_VERSION = @GFS_MAJOR_VERSION@
+GFS_MICRO_VERSION = @GFS_MICRO_VERSION@
+GFS_MINOR_VERSION = @GFS_MINOR_VERSION@
+GFS_VERSION = @GFS_VERSION@
+GREP = @GREP@
+GSL_CFLAGS = @GSL_CFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+GSL_LIBS = @GSL_LIBS@
+GTS_CFLAGS = @GTS_CFLAGS@
+GTS_CONFIG = @GTS_CONFIG@
+GTS_DEPLIBS = @GTS_DEPLIBS@
+GTS_LIBS = @GTS_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_UNDEFINED = @NO_UNDEFINED@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+W3INIT = @W3INIT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gts_cflags = @gts_cflags@
+gts_libs = @gts_libs@
+have_awk = @have_awk@
+have_gmodule = @have_gmodule@
+have_m4 = @have_m4@
+have_pkg_config = @have_pkg_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+use_mpicc = @use_mpicc@
+INCLUDES = -I$(top_srcdir)/src -I$(includedir) -DG_LOG_DOMAIN=\"Gfs-tools\"\
+            $(GTS_CFLAGS)
+
+bin_SCRIPTS = \
+	darcs2dist \
+	bat2gts \
+	ppm2mpeg \
+	ppm2theora \
+	ppm2video \
+	gfs2gfs \
+	gfsjoin
+
+EXTRA_DIST = $(bin_SCRIPTS)
+gfs2oogl2D_SOURCES = gfs2oogl.c
+gfs2oogl2D3_SOURCES = gfs2oogl.c
+gfs2oogl3D_SOURCES = gfs2oogl.c
+gfscompare2D_SOURCES = gfscompare.c
+gfscompare2D3_SOURCES = gfscompare.c
+gfscompare3D_SOURCES = gfscompare.c
+gfsjoin2D_SOURCES = gfsjoin2.c
+gfsjoin3D_SOURCES = gfsjoin2.c
+gfs2oogl2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfs2oogl2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gfs2oogl2D_LDADD = $(GFS2D_LIBS)
+gfs2oogl2D3_LDADD = $(GFS2D3_LIBS)
+gfs2oogl3D_LDADD = $(GFS3D_LIBS)
+gfscompare2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfscompare2D3_CFLAGS = $(AM_CFLAGS) -DFTT_2D3=1
+gfscompare2D_LDADD = $(GFS2D_LIBS)
+gfscompare2D3_LDADD = $(GFS2D3_LIBS)
+gfscompare3D_LDADD = $(GFS3D_LIBS)
+gfsjoin2D_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+gfsjoin2D_LDADD = $(GFS2D_LIBS)
+gfsjoin3D_LDADD = $(GFS3D_LIBS)
+ppmcombine_CFLAGS = $(AM_CFLAGS) -DFTT_2D=1
+ppmcombine_LDADD = $(GFS2D_LIBS)
+streamanime_LDADD = $(GFS3D_LIBS)
+shapes_LDADD = $(GTS_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu tools/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p || test -f $$p1; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+gfs2oogl2D$(EXEEXT): $(gfs2oogl2D_OBJECTS) $(gfs2oogl2D_DEPENDENCIES) 
+	@rm -f gfs2oogl2D$(EXEEXT)
+	$(gfs2oogl2D_LINK) $(gfs2oogl2D_OBJECTS) $(gfs2oogl2D_LDADD) $(LIBS)
+gfs2oogl2D3$(EXEEXT): $(gfs2oogl2D3_OBJECTS) $(gfs2oogl2D3_DEPENDENCIES) 
+	@rm -f gfs2oogl2D3$(EXEEXT)
+	$(gfs2oogl2D3_LINK) $(gfs2oogl2D3_OBJECTS) $(gfs2oogl2D3_LDADD) $(LIBS)
+gfs2oogl3D$(EXEEXT): $(gfs2oogl3D_OBJECTS) $(gfs2oogl3D_DEPENDENCIES) 
+	@rm -f gfs2oogl3D$(EXEEXT)
+	$(LINK) $(gfs2oogl3D_OBJECTS) $(gfs2oogl3D_LDADD) $(LIBS)
+gfscompare2D$(EXEEXT): $(gfscompare2D_OBJECTS) $(gfscompare2D_DEPENDENCIES) 
+	@rm -f gfscompare2D$(EXEEXT)
+	$(gfscompare2D_LINK) $(gfscompare2D_OBJECTS) $(gfscompare2D_LDADD) $(LIBS)
+gfscompare2D3$(EXEEXT): $(gfscompare2D3_OBJECTS) $(gfscompare2D3_DEPENDENCIES) 
+	@rm -f gfscompare2D3$(EXEEXT)
+	$(gfscompare2D3_LINK) $(gfscompare2D3_OBJECTS) $(gfscompare2D3_LDADD) $(LIBS)
+gfscompare3D$(EXEEXT): $(gfscompare3D_OBJECTS) $(gfscompare3D_DEPENDENCIES) 
+	@rm -f gfscompare3D$(EXEEXT)
+	$(LINK) $(gfscompare3D_OBJECTS) $(gfscompare3D_LDADD) $(LIBS)
+gfsjoin2D$(EXEEXT): $(gfsjoin2D_OBJECTS) $(gfsjoin2D_DEPENDENCIES) 
+	@rm -f gfsjoin2D$(EXEEXT)
+	$(gfsjoin2D_LINK) $(gfsjoin2D_OBJECTS) $(gfsjoin2D_LDADD) $(LIBS)
+gfsjoin3D$(EXEEXT): $(gfsjoin3D_OBJECTS) $(gfsjoin3D_DEPENDENCIES) 
+	@rm -f gfsjoin3D$(EXEEXT)
+	$(LINK) $(gfsjoin3D_OBJECTS) $(gfsjoin3D_LDADD) $(LIBS)
+ppmcombine$(EXEEXT): $(ppmcombine_OBJECTS) $(ppmcombine_DEPENDENCIES) 
+	@rm -f ppmcombine$(EXEEXT)
+	$(ppmcombine_LINK) $(ppmcombine_OBJECTS) $(ppmcombine_LDADD) $(LIBS)
+shapes$(EXEEXT): $(shapes_OBJECTS) $(shapes_DEPENDENCIES) 
+	@rm -f shapes$(EXEEXT)
+	$(LINK) $(shapes_OBJECTS) $(shapes_LDADD) $(LIBS)
+streamanime$(EXEEXT): $(streamanime_OBJECTS) $(streamanime_DEPENDENCIES) 
+	@rm -f streamanime$(EXEEXT)
+	$(LINK) $(streamanime_OBJECTS) $(streamanime_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfs2oogl.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfs2oogl2D-gfs2oogl.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfs2oogl2D3-gfs2oogl.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfscompare.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfscompare2D-gfscompare.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfscompare2D3-gfscompare.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfsjoin2.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gfsjoin2D-gfsjoin2.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ppmcombine-ppmcombine.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shapes.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/streamanime.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+gfs2oogl2D-gfs2oogl.o: gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D_CFLAGS) $(CFLAGS) -MT gfs2oogl2D-gfs2oogl.o -MD -MP -MF $(DEPDIR)/gfs2oogl2D-gfs2oogl.Tpo -c -o gfs2oogl2D-gfs2oogl.o `test -f 'gfs2oogl.c' || echo '$(srcdir)/'`gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfs2oogl2D-gfs2oogl.Tpo $(DEPDIR)/gfs2oogl2D-gfs2oogl.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfs2oogl.c' object='gfs2oogl2D-gfs2oogl.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D_CFLAGS) $(CFLAGS) -c -o gfs2oogl2D-gfs2oogl.o `test -f 'gfs2oogl.c' || echo '$(srcdir)/'`gfs2oogl.c
+
+gfs2oogl2D-gfs2oogl.obj: gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D_CFLAGS) $(CFLAGS) -MT gfs2oogl2D-gfs2oogl.obj -MD -MP -MF $(DEPDIR)/gfs2oogl2D-gfs2oogl.Tpo -c -o gfs2oogl2D-gfs2oogl.obj `if test -f 'gfs2oogl.c'; then $(CYGPATH_W) 'gfs2oogl.c'; else $(CYGPATH_W) '$(srcdir)/gfs2oogl.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfs2oogl2D-gfs2oogl.Tpo $(DEPDIR)/gfs2oogl2D-gfs2oogl.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfs2oogl.c' object='gfs2oogl2D-gfs2oogl.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D_CFLAGS) $(CFLAGS) -c -o gfs2oogl2D-gfs2oogl.obj `if test -f 'gfs2oogl.c'; then $(CYGPATH_W) 'gfs2oogl.c'; else $(CYGPATH_W) '$(srcdir)/gfs2oogl.c'; fi`
+
+gfs2oogl2D3-gfs2oogl.o: gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D3_CFLAGS) $(CFLAGS) -MT gfs2oogl2D3-gfs2oogl.o -MD -MP -MF $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Tpo -c -o gfs2oogl2D3-gfs2oogl.o `test -f 'gfs2oogl.c' || echo '$(srcdir)/'`gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Tpo $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfs2oogl.c' object='gfs2oogl2D3-gfs2oogl.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D3_CFLAGS) $(CFLAGS) -c -o gfs2oogl2D3-gfs2oogl.o `test -f 'gfs2oogl.c' || echo '$(srcdir)/'`gfs2oogl.c
+
+gfs2oogl2D3-gfs2oogl.obj: gfs2oogl.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D3_CFLAGS) $(CFLAGS) -MT gfs2oogl2D3-gfs2oogl.obj -MD -MP -MF $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Tpo -c -o gfs2oogl2D3-gfs2oogl.obj `if test -f 'gfs2oogl.c'; then $(CYGPATH_W) 'gfs2oogl.c'; else $(CYGPATH_W) '$(srcdir)/gfs2oogl.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Tpo $(DEPDIR)/gfs2oogl2D3-gfs2oogl.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfs2oogl.c' object='gfs2oogl2D3-gfs2oogl.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfs2oogl2D3_CFLAGS) $(CFLAGS) -c -o gfs2oogl2D3-gfs2oogl.obj `if test -f 'gfs2oogl.c'; then $(CYGPATH_W) 'gfs2oogl.c'; else $(CYGPATH_W) '$(srcdir)/gfs2oogl.c'; fi`
+
+gfscompare2D-gfscompare.o: gfscompare.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D_CFLAGS) $(CFLAGS) -MT gfscompare2D-gfscompare.o -MD -MP -MF $(DEPDIR)/gfscompare2D-gfscompare.Tpo -c -o gfscompare2D-gfscompare.o `test -f 'gfscompare.c' || echo '$(srcdir)/'`gfscompare.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfscompare2D-gfscompare.Tpo $(DEPDIR)/gfscompare2D-gfscompare.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfscompare.c' object='gfscompare2D-gfscompare.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D_CFLAGS) $(CFLAGS) -c -o gfscompare2D-gfscompare.o `test -f 'gfscompare.c' || echo '$(srcdir)/'`gfscompare.c
+
+gfscompare2D-gfscompare.obj: gfscompare.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D_CFLAGS) $(CFLAGS) -MT gfscompare2D-gfscompare.obj -MD -MP -MF $(DEPDIR)/gfscompare2D-gfscompare.Tpo -c -o gfscompare2D-gfscompare.obj `if test -f 'gfscompare.c'; then $(CYGPATH_W) 'gfscompare.c'; else $(CYGPATH_W) '$(srcdir)/gfscompare.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfscompare2D-gfscompare.Tpo $(DEPDIR)/gfscompare2D-gfscompare.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfscompare.c' object='gfscompare2D-gfscompare.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D_CFLAGS) $(CFLAGS) -c -o gfscompare2D-gfscompare.obj `if test -f 'gfscompare.c'; then $(CYGPATH_W) 'gfscompare.c'; else $(CYGPATH_W) '$(srcdir)/gfscompare.c'; fi`
+
+gfscompare2D3-gfscompare.o: gfscompare.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D3_CFLAGS) $(CFLAGS) -MT gfscompare2D3-gfscompare.o -MD -MP -MF $(DEPDIR)/gfscompare2D3-gfscompare.Tpo -c -o gfscompare2D3-gfscompare.o `test -f 'gfscompare.c' || echo '$(srcdir)/'`gfscompare.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfscompare2D3-gfscompare.Tpo $(DEPDIR)/gfscompare2D3-gfscompare.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfscompare.c' object='gfscompare2D3-gfscompare.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D3_CFLAGS) $(CFLAGS) -c -o gfscompare2D3-gfscompare.o `test -f 'gfscompare.c' || echo '$(srcdir)/'`gfscompare.c
+
+gfscompare2D3-gfscompare.obj: gfscompare.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D3_CFLAGS) $(CFLAGS) -MT gfscompare2D3-gfscompare.obj -MD -MP -MF $(DEPDIR)/gfscompare2D3-gfscompare.Tpo -c -o gfscompare2D3-gfscompare.obj `if test -f 'gfscompare.c'; then $(CYGPATH_W) 'gfscompare.c'; else $(CYGPATH_W) '$(srcdir)/gfscompare.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfscompare2D3-gfscompare.Tpo $(DEPDIR)/gfscompare2D3-gfscompare.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfscompare.c' object='gfscompare2D3-gfscompare.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfscompare2D3_CFLAGS) $(CFLAGS) -c -o gfscompare2D3-gfscompare.obj `if test -f 'gfscompare.c'; then $(CYGPATH_W) 'gfscompare.c'; else $(CYGPATH_W) '$(srcdir)/gfscompare.c'; fi`
+
+gfsjoin2D-gfsjoin2.o: gfsjoin2.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfsjoin2D_CFLAGS) $(CFLAGS) -MT gfsjoin2D-gfsjoin2.o -MD -MP -MF $(DEPDIR)/gfsjoin2D-gfsjoin2.Tpo -c -o gfsjoin2D-gfsjoin2.o `test -f 'gfsjoin2.c' || echo '$(srcdir)/'`gfsjoin2.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfsjoin2D-gfsjoin2.Tpo $(DEPDIR)/gfsjoin2D-gfsjoin2.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfsjoin2.c' object='gfsjoin2D-gfsjoin2.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfsjoin2D_CFLAGS) $(CFLAGS) -c -o gfsjoin2D-gfsjoin2.o `test -f 'gfsjoin2.c' || echo '$(srcdir)/'`gfsjoin2.c
+
+gfsjoin2D-gfsjoin2.obj: gfsjoin2.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfsjoin2D_CFLAGS) $(CFLAGS) -MT gfsjoin2D-gfsjoin2.obj -MD -MP -MF $(DEPDIR)/gfsjoin2D-gfsjoin2.Tpo -c -o gfsjoin2D-gfsjoin2.obj `if test -f 'gfsjoin2.c'; then $(CYGPATH_W) 'gfsjoin2.c'; else $(CYGPATH_W) '$(srcdir)/gfsjoin2.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/gfsjoin2D-gfsjoin2.Tpo $(DEPDIR)/gfsjoin2D-gfsjoin2.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gfsjoin2.c' object='gfsjoin2D-gfsjoin2.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gfsjoin2D_CFLAGS) $(CFLAGS) -c -o gfsjoin2D-gfsjoin2.obj `if test -f 'gfsjoin2.c'; then $(CYGPATH_W) 'gfsjoin2.c'; else $(CYGPATH_W) '$(srcdir)/gfsjoin2.c'; fi`
+
+ppmcombine-ppmcombine.o: ppmcombine.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ppmcombine_CFLAGS) $(CFLAGS) -MT ppmcombine-ppmcombine.o -MD -MP -MF $(DEPDIR)/ppmcombine-ppmcombine.Tpo -c -o ppmcombine-ppmcombine.o `test -f 'ppmcombine.c' || echo '$(srcdir)/'`ppmcombine.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/ppmcombine-ppmcombine.Tpo $(DEPDIR)/ppmcombine-ppmcombine.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ppmcombine.c' object='ppmcombine-ppmcombine.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ppmcombine_CFLAGS) $(CFLAGS) -c -o ppmcombine-ppmcombine.o `test -f 'ppmcombine.c' || echo '$(srcdir)/'`ppmcombine.c
+
+ppmcombine-ppmcombine.obj: ppmcombine.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ppmcombine_CFLAGS) $(CFLAGS) -MT ppmcombine-ppmcombine.obj -MD -MP -MF $(DEPDIR)/ppmcombine-ppmcombine.Tpo -c -o ppmcombine-ppmcombine.obj `if test -f 'ppmcombine.c'; then $(CYGPATH_W) 'ppmcombine.c'; else $(CYGPATH_W) '$(srcdir)/ppmcombine.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/ppmcombine-ppmcombine.Tpo $(DEPDIR)/ppmcombine-ppmcombine.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ppmcombine.c' object='ppmcombine-ppmcombine.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ppmcombine_CFLAGS) $(CFLAGS) -c -o ppmcombine-ppmcombine.obj `if test -f 'ppmcombine.c'; then $(CYGPATH_W) 'ppmcombine.c'; else $(CYGPATH_W) '$(srcdir)/ppmcombine.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic clean-libtool ctags distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-binSCRIPTS install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-binSCRIPTS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/bat2gts b/tools/bat2gts
new file mode 100644
index 0000000..0b48845
--- /dev/null
+++ b/tools/bat2gts
@@ -0,0 +1,154 @@
+#!/bin/sh
+
+# reference longitude (degrees)
+rlong=174
+# reference latitude (degrees)
+rlat=-41
+# width of the domain (kilometers)
+width=500
+# coastline reference depth (m)
+coast=0.1
+# verbose output
+verbose=""
+# angle of rotation
+angle=0
+# relative error
+relative=0.05
+# reference depth
+H=5000
+
+usage()
+{
+	cat <<EOF
+Usage: bat2gts [OPTIONS] < BATHY
+
+Takes a bathymetry file (three columns: longitude, latitude (degree),
+depth (meters)) and generates a GTS depth file for the given
+domain.
+
+Options:
+	[--long=V]  set reference longitude to V (default 174 deg)
+	[--lat=V]   set reference latitude  to V (default -41 deg)
+	[--width=V] set domain width (default is 500 km)
+        [--depth=V] set reference depth to V
+                        (default is 5000 meters)
+        [--coast=V] set coastline reference depth to V
+                        (default is 0.1 meters)
+        [--rel=T]   set relative error allowed on bathymetry (default is 0.05)
+        [--angle=V] rotation of V degrees (default is 0)
+        [--verbose] display info about the process
+        [--help]    display this message and exits
+EOF
+	exit $1
+}
+
+if test $# -lt 1; then
+	usage 1 1>&2
+fi
+
+command="bat2gts $*"
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --long=*)
+      rlong=$optarg
+      ;;
+    --lat=*)
+      rlat=$optarg
+      ;;
+    --width=*)
+      width=$optarg
+      ;;
+    --depth=*)
+      H=$optarg
+      ;;
+    --coast=*)
+      coast=$optarg
+      ;;
+    --angle=*)
+      angle=$optarg;
+      ;;
+    --rel=*)
+      relative=$optarg
+      ;;
+    --verbose)
+      verbose="-v"
+      ;;
+    --help)
+      usage 0 1>&2
+      ;;
+    *)
+      usage 0 1>&2
+      ;;
+  esac
+  shift
+done
+
+proj=-Ja$rlong/$rlat/1:`echo $width | awk '{print $1*1e5}'`c
+area=-R`echo $rlong $rlat $width | awk '{
+  Pi = 3.14159265359
+  dlon = 0.71*$3/(6378.*cos ($2*Pi/180))*180./Pi
+  dlat = 0.71*$3/6378.*180./Pi
+  print $1 - dlon "/" $1 + dlon "/" $2 - dlat "/" $2 + dlat
+}'`
+
+cat <<EOF
+# Created by bat2gts
+# wdir: $PWD
+# command line: $command
+# reference depth: $H m
+EOF
+mapproject -Dc -C $proj $area |\
+  awk -v H=$H -v coast=$coast '{
+    if ($1 < 0.71 && $1 > -0.71 && $2 < 0.71 && $2 > -0.71)
+      print $1 " " $2 " " (coast - $3)/H;
+  }
+' | sort | uniq | happrox -f $verbose -r `awk -v H=$H 'BEGIN{print 1./H}'` -c $relative |\
+transform --rz $angle | transform --revert --tz 0.5
+
+cat <<EOF > lolat2xy
+gmtset D_FORMAT = %.12lf
+mapproject -Dc -C $proj $area | awk '
+BEGIN {
+  angle = $angle * 3.14159265359/180.;
+  cosa = cos (angle);
+  sina = sin (angle);
+}
+{
+  if (NF >= 2) {
+    printf ("%f %f", cosa*\$1 - sina*\$2, sina*\$1 + cosa*\$2);
+    for (i = 3; i <= NF; i++)
+      printf (" %s", \$i);
+    printf ("\n");
+  }
+  else
+    print \$0;
+}'
+EOF
+chmod +x lolat2xy
+
+cat <<EOF > xy2lolat
+gmtset D_FORMAT = %.12lf
+awk '
+BEGIN {
+  angle = - $angle * 3.14159265359/180.;
+  cosa = cos (angle);
+  sina = sin (angle);
+}
+{
+  if (NF >= 2) {
+    printf ("%f %f", cosa*\$1 - sina*\$2, sina*\$1 + cosa*\$2);
+    for (i = 3; i <= NF; i++)
+      printf (" %s", \$i);
+    printf ("\n");
+  }
+  else
+    print \$0;
+}' | mapproject -Dc -I -C $proj $area
+EOF
+chmod +x xy2lolat
diff --git a/tools/darcs2dist b/tools/darcs2dist
new file mode 100644
index 0000000..e23f097
--- /dev/null
+++ b/tools/darcs2dist
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# see ../src/darcsversion.sh
+darcsversion()
+{
+    darcs changes --last=1 --xml-output | \
+	awk 'BEGIN{RS=" ";FS="="}{if ($1 == "date") print substr($2,4,6);}'
+}
+
+usage()
+{
+	cat <<EOF
+Usage: darcs2dist [OPTIONS] PACKAGE REPOSITORY URL
+
+Updates a SourceForge snapshot using the given darcs repository.
+
+EOF
+	exit $1
+}
+
+if test $# -lt 3; then
+	usage 1 1>&2
+fi
+
+package=$1
+repo=$2
+url=$3
+
+wrkdir=`mktemp -d /tmp/darcs2dist.XXXXXX`
+cd $wrkdir
+if ( darcs get --partial $repo $package && \
+     cd $package && \
+     version=`darcsversion` && \
+     login=`echo $url | awk 'BEGIN{FS=":"}{print $1}'` && \
+     dir=`echo $url | awk 'BEGIN{FS=":"}{print $2}'` && \
+     sh autogen.sh && \
+     make && \
+     make dist && \
+     tar xzf $package-*.tar.gz && \
+     cd  $package-[0-9].[0-9].[0-9] && \
+     ./configure && make && cd .. && \
+     rm -r -f $package-[0-9].[0-9].[0-9] && tar xzf $package-*.tar.gz && \
+     mv $package-[0-9].[0-9].[0-9] $package-snapshot-$version && \
+     tar chof - $package-snapshot-$version | gzip --best -c > $package-snapshot-$version.tar.gz && \
+     cat <<EOF | sftp $login
+     cd $dir/tarballs
+     -rm $package-snapshot-*.tar.gz
+     put $package-snapshot-$version.tar.gz
+     cd $dir
+     -rm $package-snapshot.tar.gz
+     symlink tarballs/$package-snapshot-$version.tar.gz $package-snapshot.tar.gz
+EOF
+) > msg 2>&1; then
+    rm -f msg
+    status=0
+else
+    cat msg
+    rm -f msg
+    status=1
+fi
+
+rm -r -f $wrkdir
+exit $status
diff --git a/tools/gfs2gfs b/tools/gfs2gfs
new file mode 100644
index 0000000..5e49838
--- /dev/null
+++ b/tools/gfs2gfs
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+usage()
+{
+	cat <<EOF
+Usage: gfs2gfs [OPTIONS] < OLDFILE > NEWFILE
+
+Converts old Gerris simulation files to the current format.
+
+Options:
+        [--help]    display this message and exits
+EOF
+	exit $1
+}
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --help)
+      usage 0 1>&2
+      ;;
+    *)
+      usage 0 1>&2
+      ;;
+  esac
+  shift
+done
+
+sed 's/^ *GtsSurface/GfsSolid {}/g' | \
+sed 's/GtsSurfaceFile/GfsSolid/g' | \
+sed 's/surface =/solid =/g'
diff --git a/tools/gfs2oogl.c b/tools/gfs2oogl.c
new file mode 100644
index 0000000..62fe314
--- /dev/null
+++ b/tools/gfs2oogl.c
@@ -0,0 +1,1250 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "init.h"
+#include "simulation.h"
+#include "graphic.h"
+#include "solid.h"
+#include "adaptive.h"
+
+#define DEBUG 0
+
+static void merged_draw (GSList * merged, FILE * fp)
+{
+  if (merged->next != NULL) {
+    GSList * i = merged;
+
+    while (i) {
+      FttCell * cell = i->data;
+      FttCellNeighbors n;
+      FttCellFace f;  
+
+      f.cell = cell;
+      ftt_cell_neighbors (cell, &n);
+      for (f.d = 0; f.d < FTT_NEIGHBORS; f.d++)
+	if (!n.c[f.d] || !g_slist_find (merged, n.c[f.d]))
+	  ftt_face_draw (&f, fp);
+      i = i->next;
+    }
+  }
+}
+
+static gdouble local_size_ratio (GtsSegment * s, GfsDomain * domain)
+{
+  GtsPoint * p1 = GTS_POINT (s->v1);
+  GtsPoint * p2 = GTS_POINT (s->v2);
+  gdouble l = gts_point_distance (p1, p2);
+  FttVector p;
+  FttCell * cell;
+  gdouble size = G_MAXDOUBLE;
+
+  p.x = p1->x;
+  p.y = p1->y;
+  p.z = p1->z;
+  cell = gfs_domain_locate (domain, p, -1, NULL);
+  if (cell)
+    size = ftt_cell_size (cell);
+
+  p.x = p2->x;  
+  p.y = p2->y;
+  p.z = p2->z;
+  cell = gfs_domain_locate (domain, p, -1, NULL);
+  if (cell) {
+    gdouble s = ftt_cell_size (cell);
+    
+    if (size == G_MAXDOUBLE || s > size)
+      size = s;
+  }
+  
+  return size/l;
+}
+
+static gboolean stop (gdouble cost, guint nedge)
+{
+  if (cost >= 1. || nedge > 50000)
+    return TRUE;
+  return FALSE;
+}
+
+static void draw_vector (FttCell * cell, gpointer * data)
+{
+  gdouble * scale = data[0];
+  GfsVariable ** u = data[1];
+  FILE * fp = stdout;
+  FttVector pos, f;
+
+  gfs_cell_cm (cell, &pos);
+  
+  f.x = GFS_VARIABLE (cell, u[0]->i)*(*scale);
+  f.y = GFS_VARIABLE (cell, u[1]->i)*(*scale);
+#if FTT_2D
+  f.z = 0.;
+#else
+  f.z = GFS_VARIABLE (cell, u[2]->i)*(*scale);
+#endif
+  fprintf (fp, "VECT 1 3 0 3 0 %g %g %g %g %g %g %g %g %g\n",
+	   pos.x + f.x - (f.x - f.y/2.)/5.,
+	   pos.y + f.y - (f.x/2. + f.y)/5.,
+	   pos.z + f.z,
+	   pos.x + f.x,
+	   pos.y + f.y,
+	   pos.z + f.z,
+	   pos.x + f.x - (f.x + f.y/2.)/5.,
+	   pos.y + f.y + (f.x/2. - f.y)/5.,
+	   pos.z + f.z);
+  fprintf (fp, "VECT 1 2 0 2 0 %g %g %g %g %g %g\n",
+	   pos.x, pos.y, pos.z,
+	   pos.x + f.x,
+	   pos.y + f.y,
+	   pos.z + f.z);
+}
+
+static void compute_mixed_vorticity (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsVariable * u = data[1];
+  FttVector g;
+
+  g_assert (((cell)->flags & GFS_FLAG_DIRICHLET) != 0);
+  gfs_cell_dirichlet_gradient (cell, u->i, -1, GFS_STATE (cell)->solid->fv, &g);
+  if (u->component == FTT_X)
+    GFS_VARIABLE (cell, v->i) -= g.y;
+  else
+    GFS_VARIABLE (cell, v->i) += g.x;
+}
+
+static void output_mixed_vorticity (FttCell * cell, GfsVariable * v)
+{
+  gdouble size = ftt_cell_size (cell);
+  GfsSolidVector * s = GFS_STATE (cell)->solid;
+
+  printf ("%g %g %g %g\n", s->ca.x, s->ca.y, s->ca.z, 
+	  GFS_VARIABLE (cell, v->i)/size);
+}
+
+static void output_mixed_pressure (FttCell * cell, GfsVariable * p)
+{
+  GfsSolidVector * s = GFS_STATE (cell)->solid;
+
+  printf ("%g %g %g %g\n", s->ca.x, s->ca.y, s->ca.z, 
+	  gfs_dimensional_value (p, gfs_interpolate (cell, s->ca, p)));
+}
+
+static void output_mixed_variable (FttCell * cell, GfsVariable * v)
+{
+  GfsSolidVector * s = GFS_STATE (cell)->solid;
+
+  printf ("%g %g %g %g\n", s->ca.x, s->ca.y, s->ca.z,
+	  gfs_dimensional_value (v, GFS_VALUE (cell, v)));
+}
+
+/* SVertex: Header */
+
+typedef struct _SVertex         SVertex;
+
+struct _SVertex {
+  /*< private >*/
+  GtsVertex parent;
+
+  /*< public >*/
+  gdouble s;
+};
+
+#define S_VERTEX(obj)            GTS_OBJECT_CAST (obj,\
+					         SVertex,\
+					         s_vertex_class ())
+#define IS_S_VERTEX(obj)         (gts_object_is_from_class (obj,\
+						 s_vertex_class ()))
+
+/* SVertex: Object */
+
+static GtsVertexClass * s_vertex_class (void)
+{
+  static GtsVertexClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo s_vertex_info = {
+      "SVertex",
+      sizeof (SVertex),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_vertex_class ()),
+				  &s_vertex_info);
+  }
+
+  return klass;
+}
+
+typedef struct {
+  GSList *** p;
+  guint nx, ny;
+  gdouble h;
+  FttVector min, max;
+} ClosestGrid;
+
+static ClosestGrid * closest_box_grid_new (FttVector min, FttVector max,
+					   gdouble h)
+{
+  ClosestGrid * g = g_malloc (sizeof (ClosestGrid));
+  guint i;
+
+  g->max = max;
+  g->min = min;
+  g->nx = (g->max.x - g->min.x)/h + 3;
+  g->h = h;
+  g->ny = (g->max.y - g->min.y)/h + 3;
+  g->min.x -= h;
+  g->min.y -= h;
+  g->max.x = g->min.x + g->nx*g->h;
+  g->max.y = g->min.y + g->ny*g->h;
+  g->p = g_malloc (g->nx*sizeof (GSList **));
+  for (i = 0; i < g->nx; i++)
+    g->p[i] = g_malloc0 (g->ny*sizeof (GSList *));
+
+  return g;
+}
+
+static void min_max_extent (FttCell * cell, ClosestGrid * g)
+{
+  FttVector pos;
+  
+  ftt_cell_pos (cell, &pos);
+  if (pos.x > g->max.x) g->max.x = pos.x;
+  if (pos.y > g->max.y) g->max.y = pos.y;
+  if (pos.x < g->min.x) g->min.x = pos.x;
+  if (pos.y < g->min.y) g->min.y = pos.y;
+}
+
+static ClosestGrid * closest_grid_new (GfsDomain * domain, gdouble h)
+{
+  ClosestGrid * g = g_malloc (sizeof (ClosestGrid));
+  guint i;
+
+  g->max.x = - G_MAXDOUBLE;
+  g->max.y = - G_MAXDOUBLE;
+  g->max.z = - G_MAXDOUBLE;
+  g->min.x = G_MAXDOUBLE;
+  g->min.y = G_MAXDOUBLE;
+  g->min.z = G_MAXDOUBLE;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) min_max_extent, g);
+  g->nx = (g->max.x - g->min.x)/h + 3;
+  g->h = h;
+  g->ny = (g->max.y - g->min.y)/h + 3;
+  g->min.x -= h;
+  g->min.y -= h;
+  g->max.x = g->min.x + g->nx*g->h;
+  g->max.y = g->min.y + g->ny*g->h;
+  g->p = g_malloc (g->nx*sizeof (GSList **));
+  for (i = 0; i < g->nx; i++)
+    g->p[i] = g_malloc0 (g->ny*sizeof (GSList *));
+
+  return g;
+}
+
+static void closest_grid_destroy (ClosestGrid * g)
+{
+  guint i, j;
+
+  for (i = 0; i < g->nx; i++) {
+    for (j = 0; j < g->ny; j++)
+      g_slist_free (g->p[i][j]);
+    g_free (g->p[i]);
+  }
+  g_free (g->p);
+  g_free (g);
+}
+
+typedef enum {
+  INSERTED, ALREADY_THERE, CLOSED, SELFCLOSED, FINISHED, OFFSIDE
+} InsertStatus;
+
+static gdouble point_distance2 (GtsPoint * p1, GtsPoint * p2)
+{
+  return ((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y));
+}
+
+static InsertStatus closest_grid_is_insertable (ClosestGrid * g, GtsPoint * p,
+						gdouble dmin, 
+						gdouble ds)
+{
+  gint i = (p->x - g->min.x)/(g->max.x - g->min.x)*g->nx, i1;
+  gint j = (p->y - g->min.y)/(g->max.y - g->min.y)*g->ny, j1;
+
+  if (i < 0 || i >= g->nx || j < 0 || j >= g->ny)
+    return OFFSIDE;
+
+  for (i1 = i - 1; i1 <= i + 1; i1++)
+    for (j1 = j - 1; j1 <= j + 1; j1++) 
+      if (i1 >= 0 && i1 < g->nx && j1 >= 0 && j1 < g->ny) {
+	GSList * k = g->p[i1][j1];
+	while (k) {
+	  GtsPoint * p1 = k->data;
+	  
+	  if (IS_S_VERTEX (p) && IS_S_VERTEX (p1) && S_VERTEX (p1)->s >= 0.) {
+	    gdouble d = point_distance2 (p, p1);
+	    
+	    if (d == 0.) return ALREADY_THERE;
+	    if (S_VERTEX (p)->s - S_VERTEX (p1)->s >= 3.*ds && d < 0.9*ds*ds)
+	      return S_VERTEX (p1)->s == 0. ? CLOSED : SELFCLOSED;
+	  }
+	  else if ((!IS_S_VERTEX (p1) || S_VERTEX (p1)->s < 0.) &&
+		   point_distance2 (p, p1) < dmin*dmin)
+	    return FINISHED;
+	  k = k->next;
+	}
+      }
+  return INSERTED;
+}
+
+static InsertStatus closest_grid_add (ClosestGrid * g, GtsPoint * p,
+				      gdouble dmin, gdouble ds)
+{
+  InsertStatus status;
+  gint i = (p->x - g->min.x)/(g->max.x - g->min.x)*g->nx;
+  gint j = (p->y - g->min.y)/(g->max.y - g->min.y)*g->ny;
+
+  if ((status = closest_grid_is_insertable (g, p, dmin, ds)) != INSERTED)
+    return status;
+  g->p[i][j] = g_slist_prepend (g->p[i][j], p);
+  return INSERTED;
+}
+
+static void closest_grid_remove (GtsPoint * p, ClosestGrid * g)
+{
+  gint i = (p->x - g->min.x)/(g->max.x - g->min.x)*g->nx;
+  gint j = (p->y - g->min.y)/(g->max.y - g->min.y)*g->ny;
+
+  if (i < 0 || i >= g->nx || j < 0 || j >= g->ny)
+    return;
+  g->p[i][j] = g_slist_remove (g->p[i][j], p);
+}
+
+static InsertStatus insert (FttVector p, ClosestGrid * g,
+			    gdouble dmin, gdouble s, gdouble ds,
+			    GtsVertex ** vertex)
+{
+  GtsVertex * v = gts_vertex_new (s_vertex_class (), p.x, p.y, p.z);
+  InsertStatus status;
+
+  S_VERTEX (v)->s = s;
+  if ((status = closest_grid_add (g, GTS_POINT (v), dmin, ds)) != INSERTED) {
+    gts_object_destroy (GTS_OBJECT (v));
+    *vertex = NULL;
+    return status;
+  }
+  *vertex = v;
+  return INSERTED;
+}
+
+static gboolean advect (GfsDomain * domain,
+			FttCell * cell,
+			FttVector * p,
+			gdouble ds,
+			gint direction)
+{
+  FttComponent c;
+  FttVector u, ph;
+  gdouble nu = 0.;
+  guint n = 10;
+  gdouble h = ds/n;
+  gboolean ad = TRUE;
+  GfsVariable ** U = gfs_domain_velocity (domain);
+
+  while (n-- > 0 && ad) {
+    for (c = 0; c < 2/*FTT_DIMENSION*/; c++) {
+      ((gdouble *) &u)[c] = direction*gfs_interpolate (cell, *p, U[c]);
+      nu += ((gdouble *) &u)[c]*((gdouble *) &u)[c];
+    }
+    if (nu > 0.) {
+      nu = sqrt (nu);
+      ph = *p;
+      for (c = 0; c < 2/*FTT_DIMENSION*/; c++)
+	((gdouble *) &ph)[c] += h*((gdouble *) &u)[c]/(2.*nu);
+      cell = gfs_domain_locate (domain, ph, -1, NULL);
+      if (cell != NULL) {
+	nu = 0.;
+	for (c = 0; c < 2/*FTT_DIMENSION*/; c++) {
+	  ((gdouble *) &u)[c] = direction*gfs_interpolate (cell, ph, U[c]);
+	  nu += ((gdouble *) &u)[c]*((gdouble *) &u)[c];
+	}
+	if (nu > 0.) {
+	  nu = sqrt (nu);
+	  for (c = 0; c < 2/*FTT_DIMENSION*/; c++)
+	    ((gdouble *) p)[c] += h*((gdouble *) &u)[c]/nu;
+	}
+	else
+	  ad = FALSE;
+      }
+      else
+	ad = FALSE;
+    }
+    else
+      ad = FALSE;
+  }
+  return ad;
+}
+
+static InsertStatus grow_streamline (GfsDomain * domain,
+				     ClosestGrid * grid,
+				     FttVector p,
+				     gdouble dmin,
+				     gdouble rds,
+				     gint direction,
+				     GSList ** stream)
+{
+  FttCell * cell = gfs_domain_locate (domain, p, -1, NULL);
+  GtsVertex * v, * vstart = NULL;
+  gdouble s = 0.;
+  InsertStatus status = cell ? INSERTED : OFFSIDE;
+
+  while (status == INSERTED || status == ALREADY_THERE) {
+    gdouble ds = rds*ftt_cell_size (cell);
+
+    ds = MIN (dmin, ds);
+    switch ((status = insert (p, grid, dmin, s, ds, &v))) {
+    case INSERTED:
+      *stream = g_slist_prepend (*stream, v);
+#if DEBUG
+      fprintf (stderr, "%g %g\n", GTS_POINT (v)->x, GTS_POINT (v)->y);
+      fflush (stderr);
+#endif
+      if (!vstart) vstart = v;
+    case ALREADY_THERE:
+      if (advect (domain, cell, &p, ds, direction)) {
+	s += ds;
+	cell = gfs_domain_locate (domain, p, -1, NULL);
+	if (cell == NULL)
+	  status = OFFSIDE;
+      }
+      else
+	status = OFFSIDE;
+      break;
+    default:
+      ;
+    }
+  }
+  if (direction > 0) {
+    if (status == CLOSED)
+      *stream = g_slist_prepend (*stream, vstart);
+    *stream = g_slist_reverse (*stream);
+  }
+  return status;
+}
+
+static void set_not_current (SVertex * s)
+{
+  g_assert (IS_S_VERTEX (s));
+  s->s = -1.;
+}
+
+static void streamline_destroy (GSList * s, ClosestGrid * grid)
+{
+  g_slist_foreach (s, (GFunc) closest_grid_remove, grid);
+  g_slist_foreach (s, (GFunc) gts_object_destroy, NULL);
+  g_slist_free (s);
+}
+
+static GSList * streamline (GfsDomain * domain,
+			    ClosestGrid * grid,
+			    FttVector p,
+			    gdouble dmin,
+			    gdouble rds,
+			    gboolean closed)
+{
+  GSList * stream = NULL;
+  InsertStatus status = grow_streamline (domain, grid, p, dmin, rds, 1, 
+					 &stream);
+
+  if (!closed) {
+    if (status != CLOSED && status != SELFCLOSED)
+      grow_streamline (domain, grid, p, dmin, rds, -1, &stream);
+  }
+  else {
+    if (status != CLOSED && status != SELFCLOSED && status != OFFSIDE) {
+      streamline_destroy (stream, grid);
+      return NULL;
+    }
+    if (status == OFFSIDE) {
+      status = grow_streamline (domain, grid, p, dmin, rds, -1, &stream);
+      if (status != CLOSED && status != SELFCLOSED && status != OFFSIDE) {
+	streamline_destroy (stream, grid);
+	return NULL;
+      }
+    }
+  }
+  g_slist_foreach (stream, (GFunc) set_not_current, NULL);
+#if DEBUG
+  fprintf (stderr, "\n"); fflush (stderr);
+#endif
+  return stream;
+}
+
+static gboolean seed (GSList * i, 
+		      GfsDomain * domain,
+		      ClosestGrid * grid,
+		      gdouble dsep,
+		      gdouble dmin,
+		      GList ** streams,
+		      gboolean closed)
+{
+  GtsPoint * v = gts_point_new (gts_point_class (), 0., 0., 0.);
+  FttVector p;
+
+  p.z = 0.;/*-0.49;*/
+  while (i) {
+    GtsPoint * p1 = i->data;
+    i = i->next;
+    if (i) {
+      GtsPoint * p2 = i->data;
+      gdouble d = sqrt (point_distance2 (p1, p2));
+
+      if (d > 1e-6) {
+	v->x = p.x = (p1->x + p2->x)/2. - (p2->y - p1->y)*dsep/d;
+	v->y = p.y = (p1->y + p2->y)/2. + (p2->x - p1->x)*dsep/d;
+	if (gfs_domain_locate (domain, p, -1, NULL) &&
+	    closest_grid_is_insertable (grid, v, dsep, 0.) == INSERTED) {
+	  GSList * s = streamline (domain, grid, p, dmin, 0.25, closed);
+
+	  if (s) {
+	    *streams = g_list_prepend (*streams, s);
+	    gts_object_destroy (GTS_OBJECT (v));
+	    return TRUE;
+	  }
+	}
+	v->x = p.x = (p1->x + p2->x)/2. + (p2->y - p1->y)*dsep/d;
+	v->y = p.y = (p1->y + p2->y)/2. - (p2->x - p1->x)*dsep/d;
+	if (gfs_domain_locate (domain, p, -1, NULL) &&
+	    closest_grid_is_insertable (grid, v, dsep, 0.) == INSERTED) {
+	  GSList * s = streamline (domain, grid, p, dmin, 0.25, closed);
+
+	  if (s) {
+	    *streams = g_list_prepend (*streams, s);
+	    gts_object_destroy (GTS_OBJECT (v));
+	    return TRUE;
+	  }
+	}
+      }
+      i = i->next;
+    }
+  }
+  gts_object_destroy (GTS_OBJECT (v));
+  return FALSE;
+}
+
+static void cell_center (FttCell * cell, gpointer * data)
+{
+  FttVector * p = data[0], pos;
+
+  if (p->x == G_MAXDOUBLE) {
+    GfsDomain * domain = data[1];
+    ClosestGrid * grid = data[2];
+    GtsPoint * v;
+
+    ftt_cell_pos (cell, &pos);
+    pos.z = 0.;
+    v = gts_point_new (gts_point_class (), pos.x, pos.y, pos.z);
+    if (gfs_domain_locate (domain, pos, -1, NULL) && 
+	closest_grid_is_insertable (grid, v, 0., 0.) == INSERTED)
+      *p = pos;
+    gts_object_destroy (GTS_OBJECT (v));
+  }
+}
+
+static GList * even_streamlines (GfsDomain * domain,
+				 ClosestGrid * grid,
+				 gdouble dsep, 
+				 gdouble dmin,
+				 gboolean closed)
+{
+  GList * streams = NULL, * current;
+  FttVector p = {G_MAXDOUBLE, G_MAXDOUBLE, G_MAXDOUBLE};
+  gboolean finished = FALSE;
+  gpointer data[3];
+
+  data[0] = &p;
+  data[1] = domain;
+  data[2] = grid;
+  gfs_domain_cell_traverse (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) cell_center, data);
+  current = streams = g_list_prepend (streams, 
+			   streamline (domain, grid, p, dmin, 0.25, closed));
+  do {
+    if (!seed (current->data, domain, grid, dsep, dmin, &streams, closed)) {
+      if (current == streams)
+	finished = TRUE;
+      else
+	current = current->prev;
+    }
+  } while (!finished);
+  return streams;
+}
+
+static gdouble curve_cost (GtsPoint *  p1, GtsPoint *  p2, GtsPoint *  p3)
+{
+  GtsVector v1, v2, a;
+
+  v1[0] = p2->x - p1->x; v1[1] = p2->y - p1->y; v1[2] = p2->z - p1->z;
+  v2[0] = p3->x - p2->x; v2[1] = p3->y - p2->y; v2[2] = p3->z - p2->z;
+  gts_vector_cross (a, v1, v2);
+  return gts_vector_norm (a)/2.;
+}
+
+static GSList * simplify_stream (GSList * stream,
+				 gdouble maxcost)
+{
+  GSList * i = stream;
+  GSList * s = NULL;
+  GtsPoint * p1 = NULL, * p2 = NULL;
+  gdouble cost = 0.;
+
+  while (i) {
+    GtsPoint * p = i->data;
+
+    if (p1 == NULL) { 
+      p1 = p;
+      s = g_slist_prepend (s, p);
+    }
+    else if (p2 == NULL)
+      p2 = p;
+    else {
+      cost += curve_cost (p1, p2, p);
+      p1 = p2;
+      p2 = p;
+      if (cost > maxcost || !i->next) {
+	s = g_slist_prepend (s, p);
+	cost = 0.;
+      }
+      else
+	GTS_OBJECT (p)->reserved = p;
+    }
+    i = i->next;
+  }
+  i = stream;
+  while (i) {
+    if (GTS_OBJECT (i->data)->reserved == i->data)
+      gts_object_destroy (i->data);
+    i = i->next;
+  }
+  g_slist_free (stream);
+  return s;
+}
+
+static void write_stream (GSList * i, FILE * fp)
+{
+  guint n = g_slist_length (i);
+
+  fprintf (fp, "VECT 1 %u 0 %u 0\n", n, n);
+  while (i) {
+    GtsPoint * p = i->data;
+    fprintf (fp, "%g %g 0\n", p->x, p->y);
+    i = i->next;
+  }
+}
+
+static void update_var (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsFunction * f = data[1];
+
+  GFS_VARIABLE (cell, v->i) = gfs_function_value (f, cell);
+}
+
+static void velocity_norm (FttCell * cell, gpointer * data)
+{
+  GfsVariable * v = data[0];
+  GfsVariable ** u = data[1];
+  GFS_VARIABLE (cell, v->i) = gfs_vector_norm (cell, u);
+}
+
+int main (int argc, char * argv[])
+{
+  int c = 0;
+  GfsVariable * var = NULL;
+  GtsFile * fp;
+  GtsSurface * surface = NULL;
+  gboolean draw_surface = FALSE;
+
+  gboolean verbose = FALSE;
+  gboolean refine = FALSE;
+
+  gdouble vector = -1.;
+
+  FILE * stream = NULL;
+  gchar * streamname = NULL, * color = NULL;
+  gboolean ribbon = FALSE, lines = FALSE, squares = FALSE;
+
+  GtsBBox * box = NULL;
+
+  gdouble min = 0., max = 0.;
+  gboolean gnuplot = FALSE;
+
+  gboolean merged = FALSE;
+  gboolean reinit = FALSE;
+  gboolean mixed = FALSE;
+  gdouble even_stream = 0., rdmin = 0.5, maxcost = 2e-7;
+  FttVector bmin, bmax = { -G_MAXDOUBLE, -G_MAXDOUBLE, -G_MAXDOUBLE };
+  gboolean closed = FALSE;
+  gint level = -1;
+  gdouble iso = G_MAXDOUBLE;
+
+  FILE * profile = NULL;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"iso", required_argument, NULL, 'u'},
+      {"level", required_argument, NULL, 'L'},
+      {"closed", no_argument, NULL, 'j'},
+      {"stream", required_argument, NULL, 'f'},
+      {"dmin", required_argument, NULL, 'I'},
+      {"maxcost", required_argument, NULL, 'O'},
+      {"box", required_argument, NULL, 'b'},
+      {"profile", required_argument, NULL, 'p'},
+      {"mixed", no_argument, NULL, 'o'},
+      {"reinit", no_argument, NULL, 'i'},
+      {"merged", no_argument, NULL, 'e'},
+      {"min", required_argument, NULL, 'm'},
+      {"max", required_argument, NULL, 'M'},
+      {"squares", no_argument, NULL, 'S'},
+      {"gnuplot", no_argument, NULL, 'g'},
+      {"sx", required_argument, NULL, 'x'},
+      {"sy", required_argument, NULL, 'y'},
+      {"sz", required_argument, NULL, 'z'},
+      {"color", required_argument, NULL, 'c'},
+      {"streamlines", required_argument, NULL, 'l'},
+      {"cylinder", required_argument, NULL, 'C'},
+      {"ribbon", required_argument, NULL, 'R'},
+      {"refine", no_argument, NULL, 'r'},
+      {"surface", required_argument, NULL, 's'},
+      {"vector", required_argument, NULL, 'V'},
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, 
+			      "hvs:rV:C:R:c:x:y:z:Sm:M:eiop:f:I:O:b:jl:L:u:g",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, 
+			 "hvs:rV:C:R:c:x:y:z:Sm:M:geiop:f:I:O:b:jl:L:u:g"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'u': /* isosurface */
+      iso = atof (optarg);
+      break;
+    case 'L': /* level */
+      level = atoi (optarg);
+      break;
+    case 'j': /* closed */
+      closed = TRUE;
+      rdmin = 0.9;
+      break;
+    case 'b': { /* box */
+      gchar * s = strtok (optarg, ",");
+      guint i = 0;
+
+      while (i < 3 && s != NULL) {
+	(&bmin.x)[i++] = atof (s);
+	s = strtok (NULL, ",");
+      }
+      if (i != 3) {
+	fprintf (stderr, "gfs2oogl: expecting a number for option `--box'\n");
+	fprintf (stderr, "Try `gfs2oogl --help' for more information.\n");
+	return 1;
+      }
+      i = 0;
+      while (i < 3 && s != NULL) {
+	(&bmax.x)[i++] = atof (s);
+	s = strtok (NULL, ",");
+      }
+      if (i != 3) {
+	fprintf (stderr, "gfs2oogl: expecting a number for option `--box'\n");
+	fprintf (stderr, "Try `gfs2oogl --help' for more information.\n");
+	return 1;
+      }
+      break;
+    }
+    case 'f': /* stream */
+      even_stream = atof (optarg);
+      break;
+    case 'I': /* dmin */
+      rdmin = atof (optarg);
+      break;
+    case 'O': /* maxcost */
+      maxcost = atof (optarg);
+      break;
+    case 'p': /* profile */
+      if ((profile = fopen (optarg, "rt")) == NULL) {
+	fprintf (stderr, "gfs2oogl: cannot open file `%s'\n"
+		 "Try `gfs2oogl --help' for more information.\n", optarg);
+	return 1; /* failure */
+      }
+      break;
+   case 'o': /* mixed */
+      mixed = TRUE;
+      break;
+    case 'i': /* reinit */
+      reinit = TRUE;
+      break;
+    case 'e': /* merged */
+      merged = TRUE;
+      break;
+    case 'M': /* max */
+      max = atof (optarg);
+      break;
+    case 'm': /* min */
+      min = atof (optarg);
+      break;
+    case 'g': /* gnuplot */
+      gnuplot = TRUE;
+      break;
+    case 'S': /* squares */
+      squares = TRUE;
+      break;
+    case 'x': /* sx */
+      box = gts_bbox_new (gts_bbox_class (), NULL,
+			  atof (optarg), -G_MAXDOUBLE/2., -G_MAXDOUBLE/2.,
+			  atof (optarg), G_MAXDOUBLE/2., G_MAXDOUBLE/2.);
+      break;
+    case 'y': /* sy */
+      box = gts_bbox_new (gts_bbox_class (), NULL,
+			  -G_MAXDOUBLE/2., atof (optarg), -G_MAXDOUBLE/2.,
+			  G_MAXDOUBLE/2., atof (optarg), G_MAXDOUBLE/2.);
+      break;
+    case 'z': /* sz */
+      box = gts_bbox_new (gts_bbox_class (), NULL,
+			  -G_MAXDOUBLE/2., -G_MAXDOUBLE/2., atof (optarg),
+			  G_MAXDOUBLE/2., G_MAXDOUBLE/2., atof (optarg));
+      break;
+    case 's': /* surface */
+      draw_surface = TRUE;
+      if (strcmp (optarg, "solid")) {
+	FILE * fp = fopen (optarg, "rt");
+	GtsFile * f;
+	
+	if (fp == NULL) {
+	  fprintf (stderr, 
+		   "gfs2oogl: cannot open file `%s'\n"
+		   "Try `gfs2oogl --help' for more information.\n",
+		   optarg);
+	  return 1; /* failure */
+	}
+	f = gts_file_new (fp);
+	surface = gts_surface_new (gts_surface_class (),
+				   gts_face_class (),
+				   gts_edge_class (),
+				   gts_vertex_class ());
+	if (gts_surface_read (surface, f)) {
+	  fprintf (stderr, "gfs2oogl: file `%s' is not a valid GTS file\n", 
+		   optarg);
+	  fprintf (stderr, "%s:%d:%d: %s\n",
+		   optarg, f->line, f->pos, f->error);
+	  return 1; /* failure */
+	}
+	gts_file_destroy (f);
+	fclose (fp);
+      }
+      break;
+    case 'l': /* lines */
+      lines = TRUE;
+      /* fall through */
+    case 'R': /* ribbon */
+      ribbon = TRUE;
+      /* fall through */
+    case 'C': /* cylinder */
+      stream = fopen (optarg, "rt");
+      streamname = g_strdup (g_basename (optarg));
+      if (stream == NULL) {
+	fprintf (stderr, 
+		 "gfs2oogl: cannot open file `%s'\n"
+		 "Try `gfs2oogl --help' for more information.\n",
+		 optarg);
+	return 1; /* failure */
+      }
+      break;
+    case 'V': /* vector */
+      vector = atof (optarg);
+      break;
+    case 'r': /* refine */
+      refine = TRUE;
+      break;
+    case 'c': /* color */
+      color = g_strdup (optarg);
+      break;
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+     "Usage: gfs2oogl [OPTION] < GFS_FILE\n"
+     "Converts a Gerris simulation file to other (graphical) formats.\n"
+     "\n"
+     "  -u V    --iso=V       outputs a GTS file isosurface for value V\n"
+     "                        the variable needs to be specified using -c\n"
+     "  -f D    --stream=D    draw evenly-spaced streamlines (D is the spacing)\n"
+     "  -I M    --dmin=M      controls length of evenly-spaced streamlines\n"
+     "                        default is 0.5\n"
+     "  -O M    --maxcost=M   controls compression of streamlines (default is 2e-7)\n"
+     "  -b x,.. --box=x,y,..  specify bounding box for streamline calculation\n"
+     "  -j      --closed      outputs only closed streamlines\n"
+     "  -p F    --profile=F   output list of values for coordinates defined in F\n"
+     "  -o      --mixed       output text values in mixed cells only\n"
+     "  -L L    --level=L     use cells at level L only\n"
+     "  -i      --reinit      reinitializes refinement and solid fractions\n"
+     "  -e      --merged      draw boundaries of merged cells\n"
+     "  -S      --squares     draw (colored) squares\n"
+     "  -g      --gnuplot     output gnuplot data\n"
+     "  -x VAL  --sx=VAL      outputs a GTS surface, cross section for x = VAL\n"
+     "                        of the scalar variable\n"
+     "  -y VAL  --sy=VAL      outputs a GTS surface, cross section for y = VAL\n"
+     "                        of the scalar variable\n"
+     "  -z VAL  --sz=VAL      outputs a GTS surface, cross section for z = VAL\n"
+     "                        of the scalar variable\n"
+     "  -s S    --surface=S   outputs the surface defined by file S (or the solid\n"
+     "                        surface is S is equal to `solid')\n"
+     "  -V S    --vector=S    output an OOGL representation of the velocity vector\n"
+     "                        field in the mixed cells\n"
+     "  -l F    --streamlines=F  draw streamlines starting from each point defined\n"
+     "                        in file F\n"
+     "  -C F    --cylinder=F  draw stream cylinders starting from each point defined\n"
+     "                        in file F\n"
+     "  -R F    --ribbon=F    draw stream ribbons starting from each point defined\n"
+     "                        in file F\n"
+     "  -r                    refines the solid surface according to the local\n"
+     "                        resolution\n"
+     "  -c V    --color=V     color surfaces, streamlines etc... according to the\n"
+     "  -m V    --min=V       set minimum scalar value to V\n"
+     "  -M V    --max=V       set maximum scalar value to V\n"
+     "  -v      --verbose     display statistics and other info\n"
+     "  -h      --help        display this help and exit\n"
+     "\n"
+     "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `gfs2oogl --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  fp = gts_file_new (stdin);
+
+  while (fp->type == GTS_INT) {
+    GfsSimulation * simulation;
+    GfsDomain * domain;
+    GtsRange stats;
+      
+    if (!(simulation = gfs_simulation_read (fp))) {
+      fprintf (stderr, 
+	       "gfs2oogl: file on standard input is not a valid simulation file\n"
+	       "<stdin>:%d:%d: %s\n",
+	       fp->line, fp->pos, fp->error);
+      return 1;
+    }
+    gfs_simulation_init (simulation);
+
+    domain = GFS_DOMAIN (simulation);
+
+    if (color) {
+      GtsFile * fp = gts_file_new_from_string (color);
+      GfsFunction * f = gfs_function_new (gfs_function_class (), 0.);
+ 
+      gfs_function_read (f, domain, fp);
+      if (fp->type == GTS_ERROR) {
+	fprintf (stderr, 
+		 "gfs2oogl: incorrect `color' argument\n"
+		 "%d: %s\n",
+		 fp->pos, fp->error);
+	return 1;
+      }
+      gts_file_destroy (fp);
+      g_free (color);
+      
+      if (!(var = gfs_function_get_variable (f))) {
+	gpointer data[2];
+
+	data[0] = var = gfs_temporary_variable (domain);
+	data[1] = f;
+	gfs_domain_cell_traverse (domain,
+				  FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				  (FttCellTraverseFunc) update_var, data);
+      }
+      gts_object_destroy (GTS_OBJECT (f));
+    }
+
+    if (verbose)
+      fprintf (stderr, "gfs2oogl: processing t = %10e\n", simulation->time.t);
+
+    if (reinit) {
+      gfs_clock_start (domain->timer);
+      gfs_simulation_refine (simulation);
+      gfs_simulation_init (simulation);
+      gfs_clock_stop (domain->timer);
+    }
+
+    if (var != NULL) {
+      if (min == max) {
+	stats = gfs_domain_stats_variable (domain, var, FTT_TRAVERSE_ALL, -1);
+	if (verbose)
+	  fprintf (stderr, 
+		   "min: %g avg: %g| %g max: %g n: %7d\n",
+		   stats.min, stats.mean, stats.stddev, stats.max, stats.n);
+      }
+      else {
+	stats.min = min;
+	stats.max = max;
+      }	
+    }
+    else
+      stats.min = stats.max = 0.;
+
+    if (var != NULL && gnuplot) {
+      if (mixed)
+	gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				   (FttCellTraverseFunc) output_mixed_variable, var);
+      else {
+	if (level < 0)
+	  gfs_write_gnuplot (domain, var, 
+			     FTT_TRAVERSE_LEAFS, -1, box, stdout);
+	else
+	  gfs_write_gnuplot (domain, var, 
+			     FTT_TRAVERSE_LEVEL, level, box, stdout);
+      }
+    }
+    else if (box && var != NULL) {
+      if (squares) {
+	if (level < 0)
+	  gfs_write_squares (domain, var, stats.min, stats.max, 
+			     FTT_TRAVERSE_LEAFS, -1, box, stdout);
+	else
+	  gfs_write_squares (domain, var, stats.min, stats.max, 
+			     FTT_TRAVERSE_LEVEL, level, box, stdout);
+      }
+      else
+	gfs_write_gts (domain, var, FTT_TRAVERSE_LEAFS, -1, box, stdout);
+    }
+    else if (stream) {
+      FttVector p;
+
+      rewind (stream);
+      printf ("(geometry \"%s-%g\" = LIST {\n",
+	      streamname,
+	      simulation->time.t);
+      while (fscanf (stream, "%lf %lf %lf", &p.x, &p.y, &p.z) == 3) {
+#if FTT_2D
+	gfs_draw_streamline (domain, p, stdout);
+#else /* 3D */
+	if (lines)
+	  gfs_draw_streamline (domain, p, stdout);
+	else if (ribbon)
+	  gfs_draw_stream_ribbon (domain, p, 2e-3,
+				  var, stats.min, stats.max, stdout);
+	else
+	  gfs_draw_stream_cylinder (domain, p, 5e-4, 
+				    var, stats.min, stats.max, stdout);
+#endif /* 3D */
+      }
+      printf ("})\n");
+    }
+    else if (profile) {
+      FttVector p;
+
+      if (var)
+	while (fscanf (profile, "%lf %lf %lf", &p.x, &p.y, &p.z) == 3) {
+	  FttCell * cell = gfs_domain_locate (domain, p, -1, NULL);
+	  if (cell)
+	    printf ("%g %g %g %g\n", p.x, p.y, p.z, gfs_interpolate (cell, p, var));
+	}
+      else {
+	GSList * j;
+	guint i = 4;
+
+	printf ("# 1:X 2:Y 3:Z ");
+	j = domain->variables;
+	while (j) {
+	  GfsVariable * v = j->data;
+	  printf ("%d:%s ", i++, v->name);
+	  j = j->next;
+	}
+	printf ("\n");
+	while (fscanf (profile, "%lf %lf %lf", &p.x, &p.y, &p.z) == 3) {
+	  FttCell * cell = gfs_domain_locate (domain, p, -1, NULL);
+	  if (cell) {
+	    printf ("%g %g %g ", p.x, p.y, p.z);
+	    j = domain->variables;
+	    while (j) {
+	      GfsVariable * v = j->data;
+	      printf ("%g ", gfs_interpolate (cell, p, v));
+	      j = j->next;
+	    }
+	    printf ("\n");
+	  }
+	}
+      }
+    }
+    else if (vector > 0.) {
+      GtsRange stats;
+      gdouble scale = 1.;
+      GfsVariable * norm = gfs_temporary_variable (domain);
+      gpointer data[2];
+
+      data[0] = norm;
+      data[1] = gfs_domain_velocity (domain);
+      gfs_domain_cell_traverse (domain,
+				FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				(FttCellTraverseFunc) velocity_norm, data);
+      stats = gfs_domain_stats_variable (domain, norm, FTT_TRAVERSE_LEAFS, -1);
+      gts_object_destroy (GTS_OBJECT (norm));
+      if (verbose)
+	fprintf (stderr, 
+		 "min: %g avg: %g| %g max: %g n: %7d\n",
+		 stats.min, stats.mean, stats.stddev, stats.max, stats.n);
+      if (stats.max > 0.)
+	scale = vector*ftt_level_size (gfs_domain_depth (domain))/stats.max;
+      printf ("(geometry \"vector-%g\" = LIST {\n", simulation->time.t);
+      data[0] = &scale;
+#if FTT_2D
+      if (box == NULL)
+	box = gts_bbox_new (gts_bbox_class (), NULL,
+			    0., -G_MAXDOUBLE/2., -G_MAXDOUBLE/2.,
+			    0., G_MAXDOUBLE/2., G_MAXDOUBLE/2.);
+#else /* 3D */
+      if (box == NULL)
+	gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				  (FttCellTraverseFunc) draw_vector, data);
+      else
+#endif /* 3D */
+      gfs_domain_cell_traverse_box (domain, box,
+				    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+				    (FttCellTraverseFunc) draw_vector, data);
+      printf ("})\n");
+    }
+    else if (draw_surface) {
+      GSList * l = gfs_simulation_get_solids (simulation), * i = l;
+	
+      while (i) {
+	GtsSurface * s = GFS_IS_SURFACE (GFS_SOLID (i->data)->s) ?  
+	  GFS_SURFACE (GFS_SOLID (i->data)->s)->s : NULL;
+  
+	if (s) {
+	  if (refine)
+	    gts_surface_refine (s, 
+				(GtsKeyFunc) local_size_ratio, domain,
+				NULL, NULL,
+				(GtsStopFunc) stop, NULL);
+	  gfs_draw_surface (domain, s, 
+			    var, stats.min, stats.max,
+			    stdout);
+	}
+	i = i->next;
+      }
+      g_slist_free (l);
+    }
+    else if (merged) {
+      gfs_set_merged (domain);
+      puts ("LIST {\n");
+      gfs_domain_traverse_merged (domain,
+				  (GfsMergedTraverseFunc) merged_draw, 
+				  stdout);
+      puts ("}\n");
+    }
+    else if (mixed && var->name && !strcmp (var->name, "Vorticity")) {
+      FttComponent c;
+      GfsVariable ** u, * vort = gfs_temporary_variable (domain);
+      gpointer data[2];
+
+      u = gfs_domain_velocity (domain);
+      gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				 (FttCellTraverseFunc) gfs_cell_reset, vort);
+      data[0] = vort;
+      for (c = 0; c < FTT_DIMENSION; c++) {
+	gfs_domain_surface_bc (domain, u[c]);
+	data[1] = u[c];
+	gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				   (FttCellTraverseFunc) compute_mixed_vorticity, data);
+      }
+      gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				 (FttCellTraverseFunc) output_mixed_vorticity, vort);
+      gts_object_destroy (GTS_OBJECT (vort));
+    }
+    else if (mixed && var->name && !strcmp (var->name, "P"))
+      gfs_domain_traverse_mixed (domain, FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS,
+				 (FttCellTraverseFunc) output_mixed_pressure, var);
+    else if (even_stream > 0.) {
+      GList * s, * i;
+      ClosestGrid * grid;
+
+      gfs_domain_cell_traverse (domain,
+				FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+				(FttCellTraverseFunc) gfs_cell_coarse_init, domain);
+
+      if (bmax.x == -G_MAXDOUBLE)
+	grid = closest_grid_new (domain, even_stream);
+      else
+	grid = closest_box_grid_new (bmin, bmax, even_stream);
+      i = s = even_streamlines (domain, grid, even_stream, 
+				even_stream*rdmin, closed);
+      closest_grid_destroy (grid);
+      printf ("LIST {\n");
+      while (i) {
+	i->data = simplify_stream (i->data, maxcost);
+	write_stream (i->data, stdout);
+	i = i->next;
+      }
+      printf ("}\n");
+    }
+    else if (iso < G_MAXDOUBLE && var != NULL) {
+      GtsSurface * s = gfs_isosurface (domain, var, iso, level);
+
+      gts_surface_write (s, stdout);
+      gts_object_destroy (GTS_OBJECT (s));
+    }
+    else {
+      gfs_draw_refined_boundaries (domain, stdout);
+      gfs_draw_solid_boundaries (domain, stdout);
+      gfs_draw_boundary_conditions (domain, stdout);
+    }
+
+    gts_object_destroy (GTS_OBJECT (simulation));
+  }
+
+  gts_file_destroy (fp);
+
+  return 0;
+}
diff --git a/tools/gfscompare.c b/tools/gfscompare.c
new file mode 100644
index 0000000..2f89a2c
--- /dev/null
+++ b/tools/gfscompare.c
@@ -0,0 +1,717 @@
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "graphic.h"
+#include "solid.h"
+#include "init.h"
+#include "simulation.h"
+
+#if FTT_2D
+
+/* GfsVertex: Header */
+
+typedef struct _GfsVertex         GfsVertex;
+
+struct _GfsVertex {
+  /*< private >*/
+  GtsVertex parent;
+
+  /*< public >*/
+  FttCell * cell;
+};
+
+#define GFS_VERTEX(obj)            GTS_OBJECT_CAST (obj,\
+					         GfsVertex,\
+					         gfs_vertex_class ())
+#define IS_GFS_VERTEX(obj)         (gts_object_is_from_class (obj,\
+						 gfs_vertex_class ()))
+
+static GtsVertexClass * gfs_vertex_class  (void);
+
+/* GfsVertex: Object */
+
+GtsVertexClass * gfs_vertex_class (void)
+{
+  static GtsVertexClass * klass = NULL;
+
+  if (klass == NULL) {
+    GtsObjectClassInfo gfs_vertex_info = {
+      "GfsVertex",
+      sizeof (GfsVertex),
+      sizeof (GtsVertexClass),
+      (GtsObjectClassInitFunc) NULL,
+      (GtsObjectInitFunc) NULL,
+      (GtsArgSetFunc) NULL,
+      (GtsArgGetFunc) NULL
+    };
+    klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_vertex_class ()),
+				  &gfs_vertex_info);
+  }
+
+  return klass;
+}
+
+static void add_vertex (GSList * merged, GtsSurface * s)
+{
+  FttVector cm = {0., 0., 0.};
+  gdouble ta = 0.;
+  GtsVertex * v;
+  GSList * i = merged;
+  
+  while (i) {
+    FttVector p;
+    FttCell * cell = i->data;
+    gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+
+    gfs_cell_cm (i->data, &p);
+    cm.x += a*p.x; cm.y += a*p.y; cm.z += a*p.z;
+    ta += a;
+    i = i->next;
+  }
+
+  v = gts_vertex_new (s->vertex_class, cm.x/ta, cm.y/ta, cm.z/ta);
+  g_assert (gts_delaunay_add_vertex (s, v, NULL) == NULL);
+  GFS_VERTEX (v)->cell = merged->data;
+}
+
+static GtsSurface * surface_from_domain (GfsDomain * domain)
+{
+  GtsSurface * s = gts_surface_new (gts_surface_class (),
+				    gts_face_class (),
+				    gts_edge_class (),
+				    GTS_VERTEX_CLASS (gfs_vertex_class ()));
+  GtsVertex * v1 = gts_vertex_new (s->vertex_class, -100., -100., 0.);
+  GtsVertex * v2 = gts_vertex_new (s->vertex_class,  100., -100., 0.);
+  GtsVertex * v3 = gts_vertex_new (s->vertex_class,    0.,  100., 0.);
+  GtsEdge * e1 = gts_edge_new (s->edge_class, v1, v2);
+  GtsEdge * e2 = gts_edge_new (s->edge_class, v2, v3);
+  GtsEdge * e3 = gts_edge_new (s->edge_class, v3, v1);
+  
+  gts_surface_add_face (s, gts_face_new (s->face_class, e1, e2, e3));
+  gfs_domain_traverse_merged (domain, (GfsMergedTraverseFunc) add_vertex, s);
+  gts_allow_floating_vertices = TRUE;
+  gts_object_destroy (GTS_OBJECT (v1));
+  gts_object_destroy (GTS_OBJECT (v2));
+  gts_object_destroy (GTS_OBJECT (v3));
+  gts_allow_floating_vertices = FALSE;
+
+  return s;
+}
+
+static void difference_triangulated (GfsVertex * v, gpointer * data)
+{
+  GtsSurface * s = data[0];
+  GfsVariable * var1 = data[1];
+  GfsVariable * var2 = data[2];
+  GfsVariable * e = data[3];
+  GtsFace * f = gts_point_locate (GTS_POINT (v), s, NULL);
+
+  if (f != NULL && gts_triangle_quality (GTS_TRIANGLE (f)) > 0.8) {
+    GtsVertex * v1, * v2, * v3;
+    gdouble x, x1, x2, y, y1, y2, a, b, det;
+    gdouble fv3, fv1, fv2;
+
+    gts_triangle_vertices (GTS_TRIANGLE (f), &v1, &v2, &v3);
+    x = GTS_POINT (v)->x - GTS_POINT (v1)->x;
+    y = GTS_POINT (v)->y - GTS_POINT (v1)->y;
+    x1 = GTS_POINT (v2)->x - GTS_POINT (v1)->x;
+    y1 = GTS_POINT (v2)->y - GTS_POINT (v1)->y;
+    x2 = GTS_POINT (v3)->x - GTS_POINT (v1)->x;
+    y2 = GTS_POINT (v3)->y - GTS_POINT (v1)->y;
+    det = x1*y2 - x2*y1;
+    g_assert (det != 0.);
+    a = (x*y2 - y*x2)/det;
+    b = (y*x1 - x*y1)/det;
+    fv1 = GFS_VARIABLE (GFS_VERTEX (v1)->cell, var2->i);
+    fv2 = GFS_VARIABLE (GFS_VERTEX (v2)->cell, var2->i);
+    fv3 = GFS_VARIABLE (GFS_VERTEX (v3)->cell, var2->i);
+    GTS_POINT (v)->z = GFS_VARIABLE (v->cell, e->i) = 
+      GFS_VARIABLE (v->cell, var1->i) -
+      (fv1 + a*(fv2 - fv1) + b*(fv3 - fv1));
+  }
+}
+
+#endif /* FTT_2D */
+
+static gboolean is_mixed (FttCell * cell, guint level)
+{
+  if (GFS_IS_MIXED (cell))
+    return TRUE;
+  if (!FTT_CELL_IS_ROOT (cell) && ftt_cell_level (cell) > level)
+    return is_mixed (ftt_cell_parent (cell), level);
+  return FALSE;
+}
+
+static void inject (FttCell * cell, GfsVariable * e)
+{
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren child;
+    guint i;
+
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i]) {
+	GFS_VARIABLE (child.c[i], e->i) = GFS_VARIABLE (cell, e->i);
+	inject (child.c[i], e);
+      }
+  }
+}
+
+static gboolean difference_tree (FttCell * cell,
+				 GfsDomain * ref,
+				 GfsVariable * v1,
+				 GfsVariable * v2,
+				 GfsVariable * e,
+				 gdouble period)
+{
+  guint level = ftt_cell_level (cell);
+  FttVector pos;
+  FttCell * locate;
+  gboolean added = FALSE;
+  
+  ftt_cell_pos (cell, &pos);
+  pos.x += period;
+  locate = gfs_domain_locate (ref, pos, level, NULL);
+  if (locate == NULL) {
+    pos.x -= 2.*period;
+    locate = gfs_domain_locate (ref, pos, level, NULL);
+  }
+  if (locate == NULL) {
+    fprintf (stderr, "gfscompare: the files are not comparable\n");
+    exit (1);
+  }
+  if (ftt_cell_level (locate) != level)
+    return FALSE;
+  if (!FTT_CELL_IS_LEAF (cell)) {
+    FttCellChildren child;
+    guint i;
+
+    ftt_cell_children (cell, &child);
+    for (i = 0; i < FTT_CELLS; i++)
+      if (child.c[i] && difference_tree (child.c[i], ref, v1, v2, e, period))
+	added = TRUE;
+  }
+  if (!added) {
+    GFS_VARIABLE (cell, e->i) = (GFS_VARIABLE (cell, v1->i) -
+				 GFS_VARIABLE (locate, v2->i));
+    inject (cell, e);
+  }
+  return TRUE;
+}
+
+static void difference_box (GfsBox * box, gpointer * data)
+{
+  gdouble * period = data[4];
+
+  difference_tree (box->root, data[0], data[1], data[2], data[3], *period);
+}
+
+static void difference_constant (FttCell * cell, gpointer * data)
+{
+  gint full = *((gint *) data[0]);
+  gdouble * sum = data[1];
+  gboolean * centered = data[3];
+  gboolean * weighted = data[4];
+  gdouble * weight = data[5];
+  GfsVariable * e = data[6];
+  gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+
+  if ((full == -2 || 
+       (full == -1 && !GFS_IS_MIXED (cell)) ||
+       (full >= 0 && !is_mixed (cell, full))) &&
+      (!(*centered) || a >= 0.5)) {
+    gdouble w = *weighted ? ftt_cell_volume (cell)*a : 1.;
+
+    *sum += w*GFS_VARIABLE (cell, e->i);
+    *weight += w;
+  }
+}
+
+static void difference (FttCell * cell, gpointer * data)
+{
+  gint full = *((gint *) data[0]);
+  GfsNorm * norm = data[1];
+  gboolean * histogram = data[2];
+  gboolean * centered = data[3];
+  gboolean * weighted = data[4];
+  gdouble * constant = data[5];
+  gboolean * mixed = data[6];
+  GfsVariable * e = data[7];
+  gdouble a = GFS_IS_MIXED (cell) ? GFS_STATE (cell)->solid->a : 1.;
+
+  if ((!(*mixed) || a < 1.) &&
+      (full == -2 || 
+       (full == -1 && !GFS_IS_MIXED (cell)) ||
+       (full >= 0 && !is_mixed (cell, full))) &&
+      (!(*centered) || a >= 0.5)) {
+    gfs_norm_add (norm, GFS_VARIABLE (cell, e->i) - *constant,
+		  *weighted ? ftt_cell_volume (cell)*a : 1.);
+    if (*histogram)
+      printf ("%g %g\n", GFS_VARIABLE (cell, e->i), a);
+  }
+  else
+    GFS_VARIABLE (cell, e->i) = 0.;
+}
+
+static void compute_gradient (FttCell * cell, gpointer * data) 
+{
+  GfsVariable * v = data[0];
+  FttComponent * c = data[1];
+  GfsVariable * g = data[2];
+
+  GFS_VARIABLE (cell, g->i) = 
+    gfs_center_gradient (cell, *c, v->i)/ftt_cell_size (cell);
+}
+
+static void compute_log (FttCell * cell, GfsVariable * e) 
+{
+  GFS_VARIABLE (cell, e->i) = log10 (fabs (GFS_VARIABLE (cell, e->i)) + 1e-10);
+}
+
+static void compute_absolute (FttCell * cell, GfsVariable * e)
+{
+  GFS_VARIABLE (cell, e->i) =  fabs (GFS_VARIABLE (cell, e->i));
+}
+
+static void difference_centered (FttCell * cell, gpointer * data)
+{
+  GfsDomain * ref = data[0];
+  GfsVariable * v1 = data[1];
+  GfsVariable * v2 = data[2];
+  GfsVariable * e = data[3];
+  FttVector p;
+  FttCell * locate;
+
+  gfs_cell_cm (cell, &p);
+  locate = gfs_domain_locate (ref, p, -1, NULL);
+  if (locate == NULL || ftt_cell_level (locate) < ftt_cell_level (cell)) {
+    fprintf (stderr, "gfscompare: the files are not comparable\n");
+    exit (1);
+  }
+  GFS_VARIABLE (cell, e->i) = GFS_VARIABLE (cell, v1->i) - gfs_interpolate (locate, p, v2);
+}
+
+int main (int argc, char * argv[])
+{
+  GtsFile * fp;
+  FILE * f;
+  int c = 0;
+  gchar * name;
+  GfsVariable * var1, * var2, * e;
+  GfsSimulation * s1, * s2;
+  
+  gboolean verbose = FALSE;
+  gint full = -2;
+  gboolean no_check = FALSE;
+  gboolean output = FALSE;
+  gboolean squares = FALSE;
+  gboolean take_log = FALSE;
+  gchar * fname1, * fname2;
+  gdouble period = 0.;
+
+  FttComponent gradient = FTT_DIMENSION;
+
+  GfsNorm norm;
+  gpointer data[8];
+
+  gboolean refined_error = FALSE;
+  gboolean histogram = FALSE;
+  gboolean centered = FALSE;
+  gboolean weighted = TRUE;
+  gdouble constant = 0.;
+  gboolean absolute = FALSE;
+#if FTT_2D
+  gboolean gnuplot = FALSE;
+  gboolean triangulate = FALSE;
+#endif /* FTT_2D */
+  gdouble min = G_MAXDOUBLE, max = - G_MAXDOUBLE;
+  gboolean mixed = FALSE;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+#if FTT_2D
+      {"gnuplot", no_argument, NULL, 'G'},
+      {"triangulate", no_argument, NULL, 't'},
+#endif /* FTT_2D */
+      {"mixed", no_argument, NULL, 'x'},
+      {"min", required_argument, NULL, 'm'},
+      {"max", required_argument, NULL, 'M'},
+      {"period", required_argument, NULL, 'p'},
+      {"histogram", no_argument, NULL, 'H'},
+      {"refined", no_argument, NULL, 'r'},
+      {"log", no_argument, NULL, 'l'},
+      {"abs", no_argument, NULL, 'a'},
+      {"full", required_argument, NULL, 'f'},
+      {"gradient", required_argument, NULL, 'g'},
+      {"output", no_argument, NULL, 'o'},
+      {"squares", no_argument, NULL, 'S'},
+      {"nocheck", no_argument, NULL, 'n'},
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      {"centered", no_argument, NULL, 'c'},
+      {"not-weighted", no_argument, NULL, 'w'},
+      {"constant", no_argument, NULL, 'C'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "hvnog:f:lSrHp:cwCeaGm:M:xt",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "hvnog:f:lSrHp:cwCeaGm:M:xt"))) {
+#endif /* not HAVE_GETOPT_LONG */
+#if FTT_2D
+    case 'G': /* gnuplot */
+      gnuplot = TRUE;
+      break;
+    case 't': /* triangulate */
+      triangulate = TRUE;
+      break;
+#endif /* FTT_2D */
+    case 'x': /* mixed */
+      mixed = TRUE;
+      break;
+    case 'm': /* min */
+      min = atof (optarg);
+      break;
+    case 'M': /* max */
+      max = atof (optarg);
+      break;
+    case 'a': /* abs */
+      absolute = TRUE;
+      break;
+    case 'C': /* constant */
+      constant = TRUE;
+      break;
+    case 'w': /* not-weighted */
+      weighted = FALSE;
+      break;
+    case 'c': /* centered */
+      centered = TRUE;
+      break;
+    case 'p': /* period */
+      period = atof (optarg);
+      break;
+    case 'H': /* histogram */
+      histogram = TRUE;
+      break;
+    case 'r': /* refined */
+      refined_error = TRUE;
+      break;
+    case 'l': /* log */
+      take_log = TRUE;
+      break;
+    case 'f': /* full */
+      full = atoi (optarg);
+      break;
+    case 'g': /* gradient */
+      gradient = atoi (optarg);
+      if (gradient >= FTT_DIMENSION) {
+	fprintf (stderr, 
+		 "gfscompare: invalid argument for option `gradient'.\n"
+		 "Try `gfscompare --help' for more information.\n");
+	return 1; /* failure */
+      }
+      break;
+    case 'S': /* squares */
+      squares = TRUE;
+      break;
+    case 'o': /* output */
+      output = TRUE;
+      break;
+    case 'n': /* nocheck */
+      no_check = TRUE;
+      break;
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+     "Usage: gfscompare [OPTION] FILE1 FILE2 VAR\n"
+     "Computes the difference between the solutions in FILE1 and FILE2\n"
+     "for variable VAR.\n"
+     "\n"
+     "  -x    --mixed       compute error only in mixed cells\n"
+     "  -m V  --min=V       set minimum of color scale to V (used with -S)\n"
+     "  -M V  --max=V       set maximum of color scale to V\n"
+     "  -a    --abs         output the absolute value of the error field\n"
+     "  -C    --constant    apply a constant shift to one of the field, minimizing\n"
+     "                      the error between the two fields (useful for pressure)\n"
+     "  -w    --not-weighted do not use area-weighted norm estimation\n"
+     "  -c    --centered    use error estimation for cell-centered variables\n"
+     "  -p P  --period=P    shifts FILE1 by P along the x axis\n"
+     "  -H    --histogram   output (error,volume) pairs for each cell used\n"
+     "                      to compute the error norms\n"
+     "  -o    --output      output a GTS representation of the error field\n"
+     "  -S    --squares     output an OOGL representation of the error field\n"
+#if FTT_2D
+     "  -G    --gnuplot     output a gnuplot representation of the error field\n"
+     "  -t    --triangulate use center of mass triangulation\n"
+#endif /* FTT_2D */
+     "  -l    --log         output the log10 of the absolute value of the error field\n"
+     "  -f L  --full=L      compare only leaf cells descendants of a cell full at level L\n"
+     "                      or all full leaf cells if L = -1\n"
+     "  -r    --refined     display error norm on the finest grid\n"
+     "  -n    --nocheck     do not check solid fractions\n"
+     "  -g C  --gradient=C  use the C component of the gradient of VAR\n"
+     "  -v    --verbose     display difference statistics and other info\n"
+     "  -h    --help        display this help and exit\n"
+     "\n"
+     "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `gfscompare --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  if (optind >= argc) { /* missing FILE1 */  
+    fprintf (stderr, 
+	     "gfscompare: missing FILE1\n"
+	     "Try `gfscompare --help' for more information.\n");
+    return 1; /* failure */
+  }
+  fname1 = argv[optind++];
+
+  if (optind >= argc) { /* missing FILE2 */  
+    fprintf (stderr, 
+	     "gfscompare: missing FILE2\n"
+	     "Try `gfscompare --help' for more information.\n");
+    return 1; /* failure */
+  }
+  fname2 = argv[optind++];
+
+  if (optind >= argc) { /* missing VAR */  
+    fprintf (stderr, 
+	     "gfscompare: missing VAR\n"
+	     "Try `gfscompare --help' for more information.\n");
+    return 1; /* failure */
+  }
+  name = argv[optind++];
+
+  f = fopen (fname1, "rt");
+  if (f == NULL) {
+    fprintf (stderr, "gfscompare: cannot open file `%s'\n", fname1);
+    return 1;
+  }
+  fp = gts_file_new (f);
+  if (!(s1 = gfs_simulation_read (fp))) {
+    fprintf (stderr, 
+	     "gfscompare: file `%s' is not a valid simulation file\n"
+	     "%s:%d:%d: %s\n",
+	     fname1, fname1, fp->line, fp->pos, fp->error);
+    return 1;
+  }
+  gts_file_destroy (fp);
+  fclose (f);
+  gfs_simulation_init (s1);
+
+  f = fopen (fname2, "rt");
+  if (f == NULL) {
+    fprintf (stderr, "gfscompare: cannot open file `%s'\n", fname2);
+    return 1;
+  }
+  fp = gts_file_new (f);
+  if (!(s2 = gfs_simulation_read (fp))) {
+    fprintf (stderr, 
+	     "gfscompare: file `%s' is not a valid simulation file\n"
+	     "%s:%d:%d: %s\n",
+	     fname2, fname2, fp->line, fp->pos, fp->error);
+    return 1;
+  }
+  gts_file_destroy (fp);
+  fclose (f);
+  gfs_simulation_init (s2);
+
+  var1 = gfs_variable_from_name (GFS_DOMAIN (s1)->variables, name);
+  if (var1 == NULL) {
+    fprintf (stderr, 
+	     "gfscompare: unknown variable `%s' for `%s'\n"
+	     "Try `gfscompare --help' for more information.\n",
+	     name, fname1);
+    return 1; /* failure */
+  }
+
+  var2 = gfs_variable_from_name (GFS_DOMAIN (s2)->variables, name);
+  if (var2 == NULL) {
+    fprintf (stderr, 
+	     "gfscompare: unknown variable `%s' for `%s'\n"
+	     "Try `gfscompare --help' for more information.\n",
+	     name, fname2);
+    return 1; /* failure */
+  }
+
+  if (verbose) {
+    GtsRange s;
+
+    norm = gfs_domain_norm_variable (GFS_DOMAIN (s1),
+				     var1, NULL, FTT_TRAVERSE_LEAFS, -1);
+    s = gfs_domain_stats_variable (GFS_DOMAIN (s1),
+				   var1, FTT_TRAVERSE_LEAFS, -1);
+    fprintf (stderr, 
+	     "%s:\n"
+	     "  first: %g second: %g infty: %g w: %g\n"
+	     "  min: %g avg: %g | %g max: %g\n",
+	     fname1, 
+	     norm.first, norm.second, norm.infty, norm.w,
+	     s.min, s.mean, s.stddev, s.max);
+    norm = gfs_domain_norm_variable (GFS_DOMAIN (s2),
+				     var2, NULL, FTT_TRAVERSE_LEAFS, -1);
+    s = gfs_domain_stats_variable (GFS_DOMAIN (s2),
+				   var2, FTT_TRAVERSE_LEAFS, -1);
+    fprintf (stderr, 
+	     "%s:\n"
+	     "  first: %g second: %g infty: %g w: %g\n"
+	     "  min: %g avg: %g | %g max: %g\n",
+	     fname2, 
+	     norm.first, norm.second, norm.infty, norm.w,
+	     s.min, s.mean, s.stddev, s.max);
+  }
+
+  if (gradient < FTT_DIMENSION) {
+    gpointer data[3];
+    GfsVariable * g1 = gfs_temporary_variable (GFS_DOMAIN (s1));
+    GfsVariable * g2 = gfs_temporary_variable (GFS_DOMAIN (s2));
+
+    data[0] = var1;
+    data[1] = &gradient;
+    data[2] = g1;
+    gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) compute_gradient, data);
+    data[0] = var2;
+    data[2] = g2;
+    gfs_domain_cell_traverse (GFS_DOMAIN (s2), 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) compute_gradient, data);
+    var1 = g1;
+    var2 = g2;
+  }
+
+  data[0] = s2;
+  data[1] = var1;
+  data[2] = var2;
+  data[3] = e = gfs_temporary_variable (GFS_DOMAIN (s1));
+  if (centered)
+    gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) difference_centered, data);
+#if FTT_2D
+  else if (triangulate) {
+    GtsSurface * ss1, * ss2;
+    gpointer data[4];
+
+    gfs_clock_start (GFS_DOMAIN (s1)->timer);
+    gfs_clock_start (GFS_DOMAIN (s2)->timer);
+    gfs_simulation_refine (s1);
+    gfs_simulation_refine (s2);
+    gfs_set_merged (GFS_DOMAIN (s1));
+    gfs_set_merged (GFS_DOMAIN (s2));
+    gfs_clock_stop (GFS_DOMAIN (s1)->timer);
+    gfs_clock_stop (GFS_DOMAIN (s2)->timer);
+    ss1 = surface_from_domain (GFS_DOMAIN (s1));
+    ss2 = surface_from_domain (GFS_DOMAIN (s2));
+    data[0] = ss2;
+    data[1] = var1;
+    data[2] = var2;
+    data[3] = e;
+    gts_surface_foreach_vertex (ss1, (GtsFunc) difference_triangulated, data);
+  }
+#endif /* FTT_2D */
+  else {
+    gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_get_from_below_intensive, var1);
+    gfs_domain_cell_traverse (GFS_DOMAIN (s2), 
+			      FTT_POST_ORDER, FTT_TRAVERSE_NON_LEAFS, -1,
+			      (FttCellTraverseFunc) gfs_get_from_below_intensive, var2);
+    data[4] = &period;
+    gts_container_foreach (GTS_CONTAINER (s1), (GtsFunc) difference_box, data);
+  }
+
+  data[0] = &full;
+  data[2] = &histogram;
+  data[3] = &centered;
+  data[4] = &weighted;
+  if (constant) {
+    gdouble sum = 0., weight = 0.;
+
+    data[1] = &sum;
+    data[5] = &weight;
+    data[6] = e;
+    gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			      FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			      (FttCellTraverseFunc) difference_constant, data);
+    constant = weight > 0. ? sum/weight : 0.;
+  }
+  
+  gfs_norm_init (&norm);
+  data[1] = &norm;
+  data[5] = &constant;
+  data[6] = &mixed;
+  data[7] = e;
+  gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			    FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			    (FttCellTraverseFunc) difference, data);
+  gfs_norm_update (&norm);
+  if (verbose) {
+    fprintf (stderr, 
+	  "total err first: %10.3e second: %10.3e infty: %10.3e w: %g\n",
+	     norm.first, norm.second, norm.infty, norm.w);
+    if (refined_error) {
+      norm = gfs_domain_norm_variable (GFS_DOMAIN (s1),
+				       e, NULL, FTT_TRAVERSE_LEVEL,
+				       gfs_domain_depth (GFS_DOMAIN (s1)));
+      fprintf (stderr, 
+	  "refined err first: %10.3e second: %10.3e infty: %10.3e w: %g\n",
+	       norm.first, norm.second, norm.infty, norm.w);
+    }
+  }
+
+  if (output ||
+#if FTT_2D
+      gnuplot ||
+#endif /* FTT_2D */
+      squares) {
+    if (take_log)
+      gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			       FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			       (FttCellTraverseFunc) compute_log, e);
+    else if (absolute)
+      gfs_domain_cell_traverse (GFS_DOMAIN (s1), 
+			       FTT_PRE_ORDER, FTT_TRAVERSE_LEAFS, -1,
+			       (FttCellTraverseFunc) compute_absolute, e);
+    if (squares) {
+      GtsRange stats = gfs_domain_stats_variable (GFS_DOMAIN (s1), e, FTT_TRAVERSE_LEAFS, -1);
+
+      gfs_write_squares (GFS_DOMAIN (s1), e, 
+			 min < G_MAXDOUBLE ? min : stats.min, 
+			 max > - G_MAXDOUBLE ? max : stats.max,
+			 FTT_TRAVERSE_LEAFS, -1, 
+			 NULL, stdout);
+    }
+#if FTT_2D
+    else if (gnuplot)
+      gfs_write_gnuplot (GFS_DOMAIN (s1), e,
+			 FTT_TRAVERSE_LEAFS, -1, 
+			 NULL, stdout);
+#endif /* FTT_2D */
+    else
+	gfs_write_gts (GFS_DOMAIN (s1), e, FTT_TRAVERSE_LEAFS, -1, NULL, stdout);
+  }
+
+  return 0;
+}
diff --git a/tools/gfsjoin b/tools/gfsjoin
new file mode 100644
index 0000000..446d616
--- /dev/null
+++ b/tools/gfsjoin
@@ -0,0 +1,195 @@
+#!/bin/bash
+# script to join gerris output files in parallel simulations
+
+
+help ()
+{
+    echo ""
+    echo "Usage: gfsjoin Simfile Directory Rootname NP Tailname > Joined"
+    echo ""
+    echo "Simfile:        Name of the simulation file"
+    echo "Directory:      Directory where results are located"
+    echo "Rootname:       File root name"
+    echo "NP:             Number of processors"
+    echo "Tailname:       File tail name"
+    echo ""
+    exit
+}
+
+#verbose=1
+
+message ()
+{
+    if test $verbose; then
+	echo $1 > /dev/stdout
+    fi
+}
+
+errmessage ()
+{
+        echo $1 > /dev/stderr
+}
+
+
+#------------------------------------------------------------------------------
+
+#checking input
+if [ $# -ne 5 ]; then
+   if [ $1 == '-h' ]; then
+       help
+   else
+        errmessage "Input error, this command requires 5 arguments"
+        errmessage "Type gfsjoin -h for more info"
+   fi
+exit
+fi
+
+# removing all blanks and tabs immediately before the end of line.
+# Comments are also removed to avoid errors
+tmp=`mktemp -d`
+sed -e 's/#.*//' -e 's/[ ^I]*$//' -e '/^$/ d' $1 | sed '/^#/ d'  > $tmp/sim.tmp
+
+c1=$3
+c2=$5
+c3="$tmp/sim.tmp"
+numproc=$4
+dir=$2
+
+# checking operations
+y=`expr ${#c2} - 2`
+tailst=`expr substr $c2 $y 3`
+
+if [ $tailst == 'gfs' ]; then
+   compress=0
+else
+        if [ $tailst == '.gz' ]; then
+          compress=1
+          c2=`expr substr $c2 1 $[$y-1]`
+        else
+          errmessage "Your simulation file has not a valid extension ("$tailst")"
+          errmessage "The correct file extensions are either .gfs or .gz"
+          exit
+        fi
+fi
+
+p1=$(awk '/GfsSimulation/ {print $1}' $c3)
+p2=$(awk '/GfsSimulation/ {print $2}' $c3)
+
+i=1
+if [ $compress -eq 1 ]; then
+while [ $i -le $numproc ]; do
+    gunzip -q ${dir}'/'$c1$[$i-1]$c2
+    i=$[$i+1]
+done
+fi
+
+message 'Creating output................'
+
+# Variables to handle the files names
+i=0
+while [ $i -lt $numproc ]; do
+    mainfile[$i]=${dir}'/'$c1$i$c2
+    message "${mainfile[$i]}"
+    i=$[$i+1]
+done
+
+# Copying the first two lines of the simulation file
+head -2 ${mainfile[0]} > $tmp/tmp.tmp
+# Inserting the correct number of boxes and connections
+sed -e '/GfsSimulation/ s/[0-9]*/'$p1'/1' -e '/GfsSimulation/s/[0-9]*/'$p2'/2' $tmp/tmp.tmp
+
+# Copying solid file (if any)
+sed -n '/SurfaceFile/ p' $c3
+
+# The first two lines are removed because they have useless information.
+# As I have already inserted the solid, this information is also removed from the files
+i=0
+while [ $i -lt $numproc ]; do
+    nend=$(echo -n $(sed -n '/GtsSurface/,/Gfs/ p' ${mainfile[$i]} | tail -1 | awk '{print $1}' ))
+    nend=$(echo -n $(awk '$1 ~ /'$nend'/ {print NR}' ${mainfile[$i]} | head -1 ))
+    nend=$[$nend+0]
+    if [ $nend -ne 0 ]; then
+	sed -e '1,2 d' -e '/GtsSurface/,'$[$nend-1]' d' ${mainfile[$i]} > $tmp/tmpfile$i
+    else
+	more +3 ${mainfile[$i]} > $tmp/tmpfile$i
+    fi
+    i=$[$i+1]
+done
+
+#Taking the initial common arguments
+sed -n '1,/GfsBox/p' $tmp/tmpfile0 | sed '$ d' 
+
+# Creating temporal file with all the boxes (sed is used to remove the 
+# local connectivities in case they will be equal)
+# boxes in proc 0
+(sed -n '/GfsBox/,$p' $tmp/tmpfile0 | awk '
+BEGIN{}
+{
+condition1 = ( $3 == "right" || $3 == "left" || $3 == "top" || $3 == "bottom" || $3 == "front" || $3 == "back" )
+if(!(NF == 3 && condition1)) {print $0}
+}
+END{}') > $tmp/tmp.tmp
+
+# the rest of boxes
+i=1
+while [ $i -lt $numproc ]; do
+    (sed -n '/GfsBox/,$p' $tmp/tmpfile$i | awk '
+BEGIN{}
+{
+condition1= ( $3 == "right" || $3 == "left" || $3 == "top" || $3 == "bottom" || $3 == "front" || $3 == "back" )
+if(!(NF == 3 && condition1)) {print $0}
+}
+END{}') >> $tmp/tmp.tmp
+    i=$[$i+1]
+done
+
+message
+message "IMPORTANT: This script assumes that the \"id\" is in correlative order in your simulation file (not the pid)"
+message
+
+awk '$1 ~ /GfsBox/ && /id =/ {print $0}' $tmp/tmp.tmp | \
+    awk 'BEGIN{}
+     { i = 0
+       do {
+           i++
+       } while ( $i !~ /^id/ )
+        print $(i+2)
+}
+END{}' > $tmp/tmp.tmp2
+
+# The last box in the temporal file is:
+lastid=$(tail -1 $tmp/tmp.tmp2)
+# And the total number of boxes:
+numboxes=$(wc -l $tmp/tmp.tmp2 | awk '{print $1}')
+
+message "Putting boxes in order in the final file"
+# Boxes are pasted in the final file in order (it is assumed to be sequential)
+i=1
+while [ $i -le $numboxes ]; do
+    if [ $i -ne $lastid ]; then
+	message -n "$i ,"
+        n0=$(awk '{if($1 == '$i') {print NR}}' $tmp/tmp.tmp2)
+        n1=$(awk 'FNR == '$[$n0+1]' {print $1}' $tmp/tmp.tmp2)
+        # Taking the lines of this range (the last line is removed
+	# because it corresponds to the next box)
+        (awk '/id = '$i' pid/,/id = '$n1' pid/ {print $0}' $tmp/tmp.tmp | head -n -1)
+        i=$[$i+1]
+    else
+	message -n "$i ,"
+        nf=$(awk '$1 ~ /GfsBox/ && $5 == '$i' && $3 ~ /id/ {print NR}' $tmp/tmp.tmp)
+        more +$nf $tmp/tmp.tmp
+        i=$[$i+1]
+    fi
+done
+
+# Copying the global conectivities
+tail -n $p2 $c3
+
+message
+message
+if [ $compress -eq 1 ]; then
+	message 'compressing files again'
+	gzip -f -q ${dir}'/'${c1}*'.gfs'
+fi
+
+rm -rf $tmp
diff --git a/tools/gfsjoin2.c b/tools/gfsjoin2.c
new file mode 100644
index 0000000..12bbabc
--- /dev/null
+++ b/tools/gfsjoin2.c
@@ -0,0 +1,187 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001-2009 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+#include "init.h"
+#include "simulation.h"
+
+#ifdef HAVE_MPI
+# include <mpi.h>
+# include "mpi_boundary.h"
+#endif /* HAVE_MPI */
+
+static void add_box (GfsBox * box, GfsSimulation * sim)
+{
+  gts_container_add (GTS_CONTAINER (sim), GTS_CONTAINEE (box));
+}
+
+static void add_id (GfsBox * box, GPtrArray * ids)
+{
+  if (box->id > ids->len)
+    g_ptr_array_set_size (ids, box->id);
+  g_ptr_array_index (ids, box->id - 1) = box;
+}
+
+static void convert_boundary_mpi_into_edges (GfsBox * box, GPtrArray * ids)
+{
+#ifdef HAVE_MPI
+  FttDirection d;
+
+  for (d = 0; d < FTT_NEIGHBORS; d++)
+    if (GFS_IS_BOUNDARY_MPI (box->neighbor[d])) {
+      GfsBoundaryMpi * b = GFS_BOUNDARY_MPI (box->neighbor[d]);
+      if (b->id < 0) {
+	fprintf (stderr, 
+		 "gfsjoin: id < 0, you maybe trying to join old parallel simulation files\n");
+	exit (1);
+      }
+      GfsBox * nbox = g_ptr_array_index (ids, b->id - 1);
+      if (nbox) {
+	if (nbox->pid != b->process) {
+	  fprintf (stderr, "gfsjoin: inconsistent MPI boundary: pid = %d, nbox->pid = %d\n",
+		   b->process, nbox->pid);
+	  exit (1);
+	}
+	if (!GFS_IS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)])) {
+	  fprintf (stderr, "gfsjoin: inconsistent MPI boundary: nbox[%d] is not an MPI boundary\n",
+		   FTT_OPPOSITE_DIRECTION (d));
+	  exit (1);
+	}
+	GfsBoundaryMpi * nb = GFS_BOUNDARY_MPI (nbox->neighbor[FTT_OPPOSITE_DIRECTION (d)]);
+	if (box->pid != nb->process || box->id != nb->id) {
+	  fprintf (stderr, "gfsjoin: inconsistent MPI boundary\n"
+		   "box->pid != nb->process || box->id != nb->id\n");
+	  exit (1);
+	}
+	gts_object_destroy (GTS_OBJECT (b));
+	gts_object_destroy (GTS_OBJECT (nb));
+	gfs_gedge_new (gfs_gedge_class (), box, nbox, d);
+      }
+    }
+#endif /* HAVE_MPI */
+}
+
+int main (int argc, char * argv[])
+{
+  int c = 0;
+  gboolean verbose = FALSE, keep = FALSE;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"keep", no_argument, NULL, 'k'},
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, 
+			      "hvk",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, 
+			 "hvk"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'k': /* keep */
+      keep = TRUE;
+      break;
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+	       "Usage: gfsjoin [OPTION] NAME1 NAME2... > JOINED\n"
+	       "Joins several parallel Gerris simulation files\n"
+	       "\n"
+	       "  -k      --keep        keep MPI boundaries\n"
+	       "  -v      --verbose     display statistics and other info\n"
+	       "  -h      --help        display this help and exit\n"
+	       "\n"
+	       "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `gfsjoin --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+#ifndef HAVE_MPI
+  fprintf (stderr, 
+	   "gfsjoin: only works for MPI version of Gerris\n"
+	   "Try `gfsjoin --help' for more information.\n");
+  return 1; /* failure */
+#endif
+
+  if (optind >= argc) { /* missing NAME */
+    fprintf (stderr, 
+	     "gfsjoin: missing NAME\n"
+	     "Try `gfsjoin --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+  GfsSimulation ** sim = g_malloc (sizeof (GfsSimulation *)*(argc - optind));
+  for (c = optind; c < argc; c++) {
+    FILE * fptr = fopen (argv[c], "r");
+    if (fptr == NULL) {
+      fprintf (stderr, "gfsjoin: cannot open file `%s'\n", argv[c]);
+      return 1; /* failure */
+    }
+    GtsFile * fp = gts_file_new (fptr);    
+    if (!(sim[c - optind] = gfs_simulation_read (fp))) {
+      fprintf (stderr, 
+	       "gfsjoin: file `%s' is not a valid simulation file\n"
+	       "%s:%d:%d: %s\n",
+	       argv[c], argv[c], fp->line, fp->pos, fp->error);
+      return 1;
+    }
+    if (verbose)
+      fprintf (stderr, "%s: %d box(es), %d cells\n", argv[c],
+	       gts_container_size (GTS_CONTAINER (sim[c - optind])),
+	       gfs_domain_size (GFS_DOMAIN (sim[c - optind]), FTT_TRAVERSE_LEAFS, -1));
+  }
+
+  /* Add all boxes to first simulation */
+  for (c = 1; c < argc - optind; c++)
+    gts_container_foreach (GTS_CONTAINER (sim[c]), (GtsFunc) add_box, sim[0]);
+
+  if (!keep) {
+    /* Create array for fast linking of ids to GfsBox pointers */
+    GPtrArray * ids = g_ptr_array_new ();
+    gts_container_foreach (GTS_CONTAINER (sim[0]), (GtsFunc) add_id, ids);
+    
+    /* Convert GfsBoundaryMpi into graph edges */
+    gts_container_foreach (GTS_CONTAINER (sim[0]), (GtsFunc) convert_boundary_mpi_into_edges, ids);
+
+    g_ptr_array_free (ids, TRUE);
+  }
+
+  gfs_simulation_write (sim[0], -1, stdout);
+
+  return 0;
+}
diff --git a/tools/ppm2mpeg b/tools/ppm2mpeg
new file mode 100644
index 0000000..6e47045
--- /dev/null
+++ b/tools/ppm2mpeg
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if test -z "`which ffmpeg`"; then
+    echo "ppm2mpeg: error: could not find 'ffmpeg'" > /dev/stderr
+    exit 1
+fi
+
+command="ffmpeg -f image2pipe -vcodec ppm -i - -vcodec mpeg1video -b 1800K -f mpeg1video"
+while test $# -gt 0; do
+    command="$command $1"
+    shift
+done
+
+if test -d "$TMPDIR" ; then
+  log=`mktemp $TMPDIR/ppm2mpeg.XXXXXX`
+else
+  log=`mktemp /tmp/ppm2mpeg.XXXXXX`
+fi
+
+if $command - 2> $log; then :
+else
+    cat $log > /dev/stderr
+    rm -f $log
+    exit 1
+fi
+rm -f $log
+
+exit 0
diff --git a/tools/ppm2theora b/tools/ppm2theora
new file mode 100644
index 0000000..9e8e14d
--- /dev/null
+++ b/tools/ppm2theora
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+if test -z "`which ffmpeg2theora`"; then
+    echo "ppm2theora: error: could not find 'ffmpeg2theora'" > /dev/stderr
+    exit 1
+fi
+
+# command="ffmpeg -f image2pipe -vcodec ppm -i - -f avi -vcodec libtheora -vb 1800K"
+command="ffmpeg2theora -f image2pipe pipe:.ppm -K 8 -v 10 --artist Gerris -o /dev/stdout"
+while test $# -gt 0; do
+    command="$command $1"
+    shift
+done
+
+if test -d "$TMPDIR" ; then
+  log=`mktemp $TMPDIR/ppm2theora.XXXXXX`
+else
+  log=`mktemp /tmp/ppm2theora.XXXXXX`
+fi
+
+if $command 2> $log; then :
+else
+    cat $log > /dev/stderr
+    rm -f $log
+    exit 1
+fi
+rm -f $log
+
+exit 0
diff --git a/tools/ppm2video b/tools/ppm2video
new file mode 100644
index 0000000..140505b
--- /dev/null
+++ b/tools/ppm2video
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+if test -z "`which ffmpeg`"; then
+    echo "ppm2video: error: could not find 'ffmpeg'" > /dev/stderr
+    exit 1
+fi
+
+command="ffmpeg -f image2pipe -vcodec ppm -i -"
+while test $# -gt 0; do
+    command="$command $1"
+    shift
+done
+
+if test -d "$TMPDIR" ; then
+  log=`mktemp $TMPDIR/ppm2video.XXXXXX`
+else
+  log=`mktemp /tmp/ppm2video.XXXXXX`
+fi
+
+if $command 2> $log; then :
+else
+    cat $log > /dev/stderr
+    rm -f $log
+    exit 1
+fi
+rm -f $log
+
+exit 0
diff --git a/tools/ppmcombine.c b/tools/ppmcombine.c
new file mode 100644
index 0000000..ee97343
--- /dev/null
+++ b/tools/ppmcombine.c
@@ -0,0 +1,91 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "graphic.h"
+
+int main (int argc, char * argv[])
+{
+  int c = 0;
+  gboolean verbose = FALSE;
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "hv",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "hv"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+     "Usage: ppmcombine [OPTION] FILE1 FILE2...\n"
+     "Combines several PPM files produced by a parallel run of Gerris.\n"
+     "\n"
+     "  -v      --verbose     display statistics and other info\n"
+     "  -h      --help        display this help and exit\n"
+     "\n"
+     "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `ppmcombine --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  if (optind >= argc) {
+    fprintf (stderr, 
+	     "ppmcombine: missing FILE1\n"
+	     "Try `ppmcombine --help' for more information.\n");
+    return 1; /* failure */
+  }
+
+#if FTT_2D
+  c = gfs_combine_ppm (&argv[optind], argc - optind, stdout);
+  if (c >= 0) {
+    fprintf (stderr,
+	     "ppmcombine: format error in file `%s'\n",
+	     argv[optind + c]);
+    return 1; /* failure */
+  }
+#endif /* 2D only */
+
+  return 0;
+}
diff --git a/tools/shapes.c b/tools/shapes.c
new file mode 100644
index 0000000..d8f725e
--- /dev/null
+++ b/tools/shapes.c
@@ -0,0 +1,581 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <gts.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifndef PI
+# define PI 3.14159265359
+#endif
+
+static GtsSurface * triangulate (GSList * vertices,
+				 GSList * constraints)
+{
+  GtsVertex * v1, * v2, * v3;
+  GtsSurface * s;
+  GSList * i;
+
+  v1 = gts_vertex_new (gts_vertex_class (), -1e10, -1e10, 0.);
+  v2 = gts_vertex_new (gts_vertex_class (), 1e10, -1e10, 0.);
+  v3 = gts_vertex_new (gts_vertex_class (), 0., 1e10, 0.);
+  s = gts_surface_new (gts_surface_class (), 
+		       gts_face_class (),
+		       gts_edge_class (),
+		       gts_vertex_class ());
+  gts_surface_add_face (s, gts_face_new (gts_face_class (), 
+				gts_edge_new (gts_edge_class (), v1, v2),
+				gts_edge_new (gts_edge_class (), v2, v3),
+				gts_edge_new (gts_edge_class (), v3, v1)));
+  i = vertices;
+  while (i) {
+    if (gts_delaunay_add_vertex (s, i->data, NULL) != NULL) {
+      gts_object_destroy (GTS_OBJECT (s));
+      return NULL;
+    }
+    i = i->next;
+  }
+  
+  i = constraints;
+  while (i) {
+    if (gts_delaunay_add_constraint (s, i->data) != NULL) {
+      gts_object_destroy (GTS_OBJECT (s));
+      return NULL;
+    }
+    i = i->next;
+  }
+  
+  gts_delaunay_remove_hull (s);
+
+  return s;
+}
+
+static GSList * contour (GSList * i, GtsSurface * s, 
+			 gdouble z, gboolean closed)
+{
+  GSList * edges = NULL;
+  GtsVertex * vold = NULL, * vin = NULL;
+
+  if (i == NULL || i->next == NULL)
+    return NULL;
+
+  while (i) {
+    GtsPoint * p = i->data;
+    GtsVertex * v;
+
+    v = gts_vertex_new (s->vertex_class, p->x, p->y, z);
+    if (vold)
+      edges = g_slist_prepend (edges, 
+	  gts_edge_new (GTS_EDGE_CLASS (gts_constraint_class ()), v, vold));
+    else
+      vin = v;
+    vold = v;
+    i = i->next;
+  }
+  if (closed)
+    edges = g_slist_prepend (edges, 
+	  gts_edge_new (GTS_EDGE_CLASS (gts_constraint_class ()), vin, vold));
+  return edges;
+}
+
+static void surface_add_shape (GtsSurface * s, 
+			       GSList * shape,
+			       gdouble z1,
+			       gdouble z2,
+			       guint nz,
+			       gboolean closed,
+			       gboolean ends)
+{
+  gdouble z, dz = (z2 - z1)/nz;
+  guint i;
+  GSList * bottom = NULL, * e1 = NULL, * e2 = NULL;
+
+  for (i = 0, z = z1; i <= nz; i++, z += dz) {
+    if (e1 == NULL)
+      bottom = e1 = contour (shape, s, z, closed);
+    else {
+      GSList * i, * j;
+      GtsEdge * eold = NULL, * ein = NULL;
+
+      e2 = contour (shape, s, z, closed);
+      i = e1; j = e2;
+      while (i && j) {
+	GtsEdge * e;
+	GtsEdge * ee = gts_edge_new (gts_edge_class (),
+				     GTS_SEGMENT (i->data)->v2,
+				     GTS_SEGMENT (j->data)->v1);
+
+	if (!closed || i->next != NULL)
+	  e = gts_edge_new (gts_edge_class (),
+			    GTS_SEGMENT (i->data)->v2,
+			    GTS_SEGMENT (j->data)->v2);
+	else
+	  e = ein;
+	if (eold == NULL)
+	  eold = ein = gts_edge_new (gts_edge_class (), 
+				     GTS_SEGMENT (i->data)->v1,
+				     GTS_SEGMENT (j->data)->v1);
+	gts_surface_add_face (s, gts_face_new (s->face_class, 
+					       i->data, eold, ee));
+	gts_surface_add_face (s, gts_face_new (s->face_class, 
+					       e, ee, j->data));
+	eold = e;
+	i = i->next; 
+	j = j->next;
+      }
+      if (e1 != bottom) g_slist_free (e1);
+      e1 = e2;
+    }
+  }
+
+  if (ends) {
+    GSList * vertices1 = gts_vertices_from_segments (bottom);
+    GSList * vertices2 = gts_vertices_from_segments (e1);
+    GtsSurface * s1 = triangulate (vertices1, bottom);
+    GtsSurface * s2 = triangulate (vertices2, e1);
+
+    if (s1 == NULL || s2 == NULL) {
+      GSList * i = shape;
+
+      while (i) {
+	fprintf (stderr, "%g %g\n", 
+		 GTS_POINT (i->data)->x, 
+		 GTS_POINT (i->data)->y); 
+	i = i->next;
+      }
+      fprintf (stderr, "\n");
+      if (s1) gts_object_destroy (GTS_OBJECT (s1));
+      if (s2) gts_object_destroy (GTS_OBJECT (s2));
+    }
+    else {
+      gts_surface_foreach_face (s2, (GtsFunc) gts_triangle_revert, NULL);
+      
+      gts_surface_merge (s, s1);
+      gts_surface_merge (s, s2);
+    
+      gts_object_destroy (GTS_OBJECT (s1));
+      gts_object_destroy (GTS_OBJECT (s2));
+    }
+    g_slist_free (vertices1);
+    g_slist_free (vertices2);
+  }
+
+  g_slist_free (bottom);
+  g_slist_free (e1);
+}
+
+static void surface_add_ellipse_shape (GtsSurface * s,
+				       gdouble x, gdouble y,
+				       gdouble radius,
+				       gdouble theta,
+				       gdouble thetamax,
+				       gdouble e,
+				       gdouble z1, gdouble z2,
+				       guint np,
+				       gboolean closed)
+{
+  GSList * shape = NULL;
+  guint i, npm = np;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (np >= 3);
+
+  if (thetamax < 2.*PI)
+    npm = np + 1;
+  for (i = 0; i < npm; i++) {
+    gdouble theta1 = theta + i*thetamax/(gdouble) np;
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (),
+					    x + radius*e*cos (theta1),
+					    y + radius/e*sin (theta1),
+					    0.));
+  }
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, closed);
+  g_slist_free (shape);
+}
+
+static void surface_add_star_shape (GtsSurface * s,
+				    gdouble dr,
+				    gdouble z1, gdouble z2,
+				    guint np,
+				    gboolean closed)
+{
+  GSList * shape = NULL;
+  guint i;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (np >= 3);
+
+  for (i = 0; i < np; i++) {
+    gdouble theta = .001 + 2.*i*PI/np;
+    gdouble radius = 0.45 - dr + dr*cos (6.*theta);
+
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (),
+					    radius*cos (theta),
+					    radius*sin (theta),
+					    0.));
+  }
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, closed);
+  g_slist_free (shape);
+}
+
+static gdouble shape_func_bottom (gdouble x)
+{
+  gdouble y1 = 0.2/4.;
+  gdouble y2 = 1e-6/4.;
+
+  if (x <= -0.25)
+    return y1;
+  if (x < 0.25)
+    return y2 + 0.5*(y1 - y2)*(1. + cos (2.*PI*(x + 0.25)));
+  return y2;
+}
+
+static void surface_add_channel_shape (GtsSurface * s,
+				       gdouble z1, gdouble z2,
+				       guint np,
+				       gboolean closed)
+{
+  GSList * shape = NULL;
+  gint i;
+
+  g_return_if_fail (s != NULL);
+
+  for (i = np - 1; i >= 0; i--) {
+    gdouble x = - 0.501 + 1.002*(gdouble) i/(gdouble) (np - 1);
+    gdouble y = shape_func_bottom (x) - 0.125;
+
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (), x, y, 0.));
+  }
+  for (i = 0; i < np; i++) {
+    gdouble x = - 0.501 + 1.002*(gdouble) i/(gdouble) (np - 1);
+    gdouble y = 0.25 - shape_func_bottom (x) - 0.125;
+
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (), x, y, 0.));
+  }
+  shape = g_slist_reverse (shape);
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, closed);
+  g_slist_free (shape);
+}
+
+static void surface_add_rectangular_channel_shape (GtsSurface * s,
+						   gdouble z1, gdouble z2,
+						   gboolean closed)
+{
+  GSList * shape = NULL;
+
+  g_return_if_fail (s != NULL);
+
+  shape = g_slist_prepend (shape, 
+		  gts_point_new (gts_point_class (), -0.5001, -0.125001, 0.));
+  shape = g_slist_prepend (shape, 
+		  gts_point_new (gts_point_class (), -0.5001,  0.125001, 0.));
+  shape = g_slist_prepend (shape, 
+		  gts_point_new (gts_point_class (),  0.5001, 0.125001, 0.));
+  shape = g_slist_prepend (shape, 
+		  gts_point_new (gts_point_class (),  0.5001, -0.125001, 0.));
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, closed);
+  g_slist_free (shape);
+}
+
+static void surface_add_witch_shape (GtsSurface * s,
+				     gdouble xo, gdouble h, gdouble lh,
+				     gdouble z1, gdouble z2,
+				     guint np)
+{
+  GSList * shape = NULL;
+  guint i;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (np >= 2);
+  g_return_if_fail (lh > 0.);
+
+  shape = g_slist_prepend (shape, 
+			   gts_point_new (gts_point_class (),
+					  -0.5001, -0.5002, 0.));
+  for (i = 0; i < np; i++) {
+    gdouble x = -0.5001 + 1.0002*i/(gdouble) (np - 1);
+
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (),
+					    x,
+				 h/(1. + (x - xo)*(x - xo)/(lh*lh)) - 0.5001,
+					    0.));
+  }
+  shape = g_slist_prepend (shape, 
+			   gts_point_new (gts_point_class (),
+					  0.5001, -0.5002, 0.));
+  shape = g_slist_reverse (shape);
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, TRUE);
+  g_slist_free (shape);
+}
+
+static void surface_add_rayleigh_taylor_shape (GtsSurface * s,
+					       gdouble yo, gdouble a,
+					       gdouble z1, gdouble z2,
+					       guint np)
+{
+  GSList * shape = NULL;
+  guint i;
+
+  g_return_if_fail (s != NULL);
+  g_return_if_fail (np >= 2);
+
+  shape = g_slist_prepend (shape, 
+			   gts_point_new (gts_point_class (),
+					  -0.5001, -10., 0.));
+  for (i = 0; i < np; i++) {
+    gdouble x = -0.5001 + 1.0002*i/(gdouble) (np - 1);
+
+    shape = g_slist_prepend (shape, 
+			     gts_point_new (gts_point_class (),
+					    x,
+			     yo + a*cos (i*2.*M_PI/(np - 1)),
+					    0.));
+  }
+  shape = g_slist_prepend (shape, 
+			   gts_point_new (gts_point_class (),
+					  0.5001, -10., 0.));
+  shape = g_slist_reverse (shape);
+  surface_add_shape (s, shape, z1, z2, 10, TRUE, TRUE);
+  g_slist_free (shape);
+}
+
+static gboolean surface_add_file_shape (GtsSurface * s,
+					gdouble z1, gdouble z2,
+					gboolean zextrude,
+					FILE * fp)
+{
+  gdouble xs = G_MAXDOUBLE, ys = G_MAXDOUBLE, x, y;
+  GSList * shape = NULL;
+  guint length;
+  GtsSurface * s1, * self = NULL;
+
+  if (zextrude && fscanf (fp, "%lf %lf", &z1, &z2) != 2)
+    return FALSE;
+
+  while (fscanf (fp, "%lf %lf", &x, &y) == 2) {
+    if (x != xs || y != ys)
+      shape = g_slist_prepend (shape, 
+			       gts_point_new (gts_point_class (), x, y, 0));
+    if (xs == G_MAXDOUBLE) { xs = x; ys = y; }
+  }
+  fgetc (fp);
+  length = g_slist_length (shape);
+  if (length > 0 && length < 3) {
+    g_slist_free (shape);
+    return FALSE;
+  }
+  s1 = gts_surface_new (gts_surface_class (), 
+			s->face_class, s->edge_class, s->vertex_class);
+  surface_add_shape (s1, shape, z1, z2, zextrude ? 1 : 10, TRUE, TRUE);
+  if (!gts_surface_is_orientable (s1) || 
+      !gts_surface_is_closed (s1) ||
+      (self = gts_surface_is_self_intersecting (s1))) {
+    GSList * i = shape;
+    
+    while (i) {
+      fprintf (stderr, "%g %g\n", 
+	       GTS_POINT (i->data)->x, 
+	       GTS_POINT (i->data)->y); 
+      i = i->next;
+    }
+    fprintf (stderr, "\n");
+    if (self)
+      gts_object_destroy (GTS_OBJECT (self));
+  }
+  else
+    gts_surface_merge (s, s1);
+  gts_object_destroy (GTS_OBJECT (s1));
+  g_slist_free (shape);
+  return TRUE;
+}
+
+int main (int argc, char * argv[])
+{
+  GtsSurface * s;
+  guint number = 100;
+  int c = 0;
+  gchar * shape = NULL;
+  gboolean verbose = FALSE;
+  gdouble dr = 0.15;
+  gdouble ratio = 1.;
+  gboolean closed = TRUE;
+  gboolean zextrude = FALSE;
+  FILE * sfp = NULL;
+
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"zextrude", no_argument, NULL, 'z'},
+      {"number", required_argument, NULL, 'n'},
+      {"open", no_argument, NULL, 'o'},
+      {"dr", required_argument, NULL, 'd'},
+      {"ratio", required_argument, NULL, 'r'},
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "hvn:d:r:oz",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "hvn:d:r:oz"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'z': /* zextrude */
+      zextrude = TRUE;
+      break;
+    case 'o': /* open */
+      closed = FALSE;
+      break;
+    case 'n': /* number */
+      number = atoi (optarg);
+      break;
+    case 'd': /* dr */
+      dr = atof (optarg);
+      break;
+    case 'r' :/* ratio */
+      ratio = atof (optarg);
+      break;
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+     "Usage: shapes [OPTIONS] SHAPE\n"
+     "Generates various shapes. SHAPE can be one of:\n"
+     "  ellipse, star, 4ellipses, square, almgren, channel, half-cylinder,\n"
+     "  rayleigh-taylor, FILE\n"
+     "\n"
+     "  -z    --zextrude    shape file contains z coordinate\n"
+     "  -n N  --number=N    set number of points for polar surfaces (default is 100)\n"
+     "  -o    --open        generate open surfaces\n"
+     "  -d R  --dr=R        set inner radius for star to R (default is 0.15)\n"
+     "  -r R  --ratio=R     ratio x/y of the ellipse (default is 1)\n"
+     "  -v    --verbose     display surface statistics\n"
+     "  -h    --help        display this help and exit\n"
+     "\n"
+     "Reports bugs to %s\n",
+	       GTS_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `shapes --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  if (optind >= argc) { /* missing SHAPE */  
+    fprintf (stderr, 
+	     "shapes: missing SHAPE\n"
+	     "Try `shapes --help' for more information.\n");
+    return 1; /* failure */
+  }
+  shape = argv[optind++];
+
+  s = gts_surface_new (gts_surface_class (),
+		       gts_face_class (),
+		       gts_edge_class (),
+		       gts_vertex_class ());
+  if (!strcmp (shape, "ellipse"))
+    surface_add_ellipse_shape (s, 0., 0., 0.25, 0.001, 2.*PI,
+			       sqrt (1./ratio), - 1., 1., number, closed);
+  else if (!strcmp (shape, "star"))
+    surface_add_star_shape (s, dr, - 1., 1., number, closed);
+  else if (!strcmp (shape, "4ellipses")) {
+    surface_add_ellipse_shape (s, 0.25, 0.25, 5./32./sqrt (2.), 0.001, 2.*PI,
+			       sqrt (2.), - 1., 1., number, closed);
+    surface_add_ellipse_shape (s, -0.25, 0.25, 5./32./sqrt (2.), 0.001, 2.*PI,
+			       sqrt (2.), - 1., 1., number, closed);
+    surface_add_ellipse_shape (s, 0.25, -0.25, 5./32./sqrt (2.), 0.001, 2.*PI,
+			       sqrt (2.), - 1., 1., number, closed);
+    surface_add_ellipse_shape (s, -0.25, -0.25, 5./32./sqrt (2.), 0.001, 2.*PI,
+			       sqrt (2.), - 1., 1., number, closed);
+  }
+  else if (!strcmp (shape, "square"))
+    surface_add_ellipse_shape (s, 0., 0., 0.25*sqrt(2.), PI/4.,  2.*PI, 1.,
+			       - 1., 1., 4, closed);
+  else if (!strcmp (shape, "almgren")) {
+    surface_add_ellipse_shape (s, 0.25, 0.25, 0.1, 0.001,  2.*PI, 1., -1., 1., 
+			       number, closed);
+    surface_add_ellipse_shape (s, -0.25, 0.125, sqrt (0.15*0.1),
+			       0.001, 2.*PI,
+			       0.15/sqrt (0.15*0.1),
+			       -1., 1., number, closed);
+    surface_add_ellipse_shape (s, 0., -0.25, sqrt (0.2*0.1),
+			       0.001, 2.*PI,
+			       0.2/sqrt (0.2*0.1),
+			       -1., 1., number, closed);
+  }
+  else if (!strcmp (shape, "channel"))
+    surface_add_channel_shape (s, -1., 1., number, closed);
+  else if (!strcmp (shape, "half-cylinder")) {
+    //    surface_add_rectangular_channel_shape (s, -1., 1., closed);
+    surface_add_ellipse_shape (s, -0.375001, 0., 0.03125001, 
+			       PI/2., PI, 1., -1., 1., 
+			       number, closed);
+  }
+  else if (!strcmp (shape, "witch"))
+    surface_add_witch_shape (s, -0.25, 0.05, 0.05, -1., 1., number);
+  else if (!strcmp (shape, "rayleigh-taylor"))
+    surface_add_rayleigh_taylor_shape (s, 0., 0.025, -1., 1., number);
+  else if (!strcmp (shape, "annulus")) {
+    surface_add_ellipse_shape (s, 0., 0., 0.5, 0.001, 2.*PI,
+			       1., - 2., 2., number, closed);
+    gts_surface_foreach_face (s, (GtsFunc) gts_triangle_revert, NULL);
+    surface_add_ellipse_shape (s, 0., 0., 0.25, 0.001, 2.*PI,
+			       1., - 1., 1., number, closed);
+  }
+  else if ((!strcmp (shape, "-") && (sfp = stdin)) || 
+	   (sfp = fopen (shape, "rt")) != NULL) {
+    while (!feof (sfp))
+      if (!surface_add_file_shape (s, -1., 1., zextrude, sfp)) {
+	fprintf (stderr, 
+		 "shapes: file `%s' is not a valid shape\n"
+		 "Try `shapes --help' for more information.\n",
+		 shape);
+	return 1; /* failure */
+      }
+    fclose (sfp);
+  }
+  else {
+    fprintf (stderr, 
+	     "shapes: unknown shape `%s'\n"
+	     "Try `shapes --help' for more information.\n",
+	     shape);
+    return 1; /* failure */
+  }
+  if (verbose)
+    gts_surface_print_stats (s, stderr);
+  gts_surface_write (s, stdout);
+
+  return 0;
+}
+				      
diff --git a/tools/streamanime.c b/tools/streamanime.c
new file mode 100644
index 0000000..dc5ecae
--- /dev/null
+++ b/tools/streamanime.c
@@ -0,0 +1,144 @@
+/* Gerris - The GNU Flow Solver
+ * Copyright (C) 2001 National Institute of Water and Atmospheric Research
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_H
+#  include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "init.h"
+#include "simulation.h"
+#include "graphic.h"
+
+static void streamline_draw (GList * s, FILE * fp)
+{
+  guint np = g_list_length (s);
+
+  fprintf (fp, "VECT 1 %u 0 %u 0\n", np, np);
+  while (s) {
+    GtsPoint * p = s->data;
+
+    fprintf (fp, "%g %g %g\n", p->x, p->y, p->z);
+    s = s->next;
+  }
+}
+
+int main (int argc, char * argv[])
+{
+  int c = 0;
+  GtsFile * fp;
+  GfsTime time;
+  guint ns = 0;
+
+  gboolean verbose = FALSE;
+
+  gfs_init (&argc, &argv);
+
+  /* parse options using getopt */
+  while (c != EOF) {
+#ifdef HAVE_GETOPT_LONG
+    static struct option long_options[] = {
+      {"help", no_argument, NULL, 'h'},
+      {"verbose", no_argument, NULL, 'v'},
+      { NULL }
+    };
+    int option_index = 0;
+    switch ((c = getopt_long (argc, argv, "hv",
+			      long_options, &option_index))) {
+#else /* not HAVE_GETOPT_LONG */
+    switch ((c = getopt (argc, argv, "hv"))) {
+#endif /* not HAVE_GETOPT_LONG */
+    case 'v': /* verbose */
+      verbose = TRUE;
+      break;
+    case 'h': /* help */
+      fprintf (stderr,
+     "Usage: streamanime [OPTION] < STREAMLINE_FILE\n"
+     "Converts a Gerris streamline file to other (graphical) formats.\n"
+     "\n"
+     "  -v      --verbose     display statistics and other info\n"
+     "  -h      --help        display this help and exit\n"
+     "\n"
+     "Reports bugs to %s\n",
+	       FTT_MAINTAINER);
+      return 0; /* success */
+      break;
+    case '?': /* wrong options */
+      fprintf (stderr, "Try `streamanime --help' for more information.\n");
+      return 1; /* failure */
+    }
+  }
+
+  fp = gts_file_new (stdin);
+  gfs_time_init (&time);
+  while (fp->type == GTS_STRING) {
+    if (!strcmp (fp->token->str, "GfsTime")) {
+      gts_file_next_token (fp);
+      gfs_time_read (&time, fp);
+      if (fp->type == GTS_ERROR) {
+	fprintf (stderr, 
+		 "streamanime: file on standard input is not a valid streamline file\n"
+		 "<stdin>:%d:%d: %s\n",
+		 fp->line, fp->pos, fp->error);
+	return 1;
+      }
+      if (verbose)
+	fprintf (stderr, "\rstreamanime: processing t: %7.3f n: %5u", 
+		 time.t, ns);
+      gts_file_first_token_after (fp, '\n');
+      ns = 0;
+      printf ("(redraw focus)\n(freeze focus)\n");
+    }
+    else if (!strcmp (fp->token->str, "GfsStreamline")) {
+      GList * streamline = gfs_streamline_read (fp);
+
+      if (fp->type == GTS_ERROR) {
+	fprintf (stderr, 
+		 "streamanime: file on standard input is not a valid streamline file\n"
+		 "<stdin>:%d:%d: %s\n",
+		 fp->line, fp->pos, fp->error);
+	return 1;
+      }
+      printf ("(geometry \"stream-%u\" = {\n", ns++);
+      streamline_draw (streamline, stdout);
+      printf ("})\n");
+      gfs_streamline_destroy (streamline);
+    }
+    else {
+      gts_file_error (fp, "unknown identifier `%s'", fp->token->str);
+      fprintf (stderr, 
+	       "streamanime: file on standard input is not a valid streamline file\n"
+	       "<stdin>:%d:%d: %s\n",
+	       fp->line, fp->pos, fp->error);
+      return 1;
+    }
+  }
+  gts_file_destroy (fp);
+  printf ("(redraw focus)\n");
+  if (verbose)
+    fputc ('\n', stderr);
+
+  return 0;
+}

-- 
Gerris Flow Solver



More information about the debian-science-commits mailing list